I like to upgrade the ruby version from 2.4.2 to 2.5.0 in my rails application.
All specs/tests fail where I use turbolinks.
Is there a known issue with turbolinks and ruby 2.5.0?
Here is the output on the terminal.
Failure/Error: expect(request).to redirect_to company_salesmen_path(salesman.company)
NoMethodError:
undefined method `get?' for 302:Integer
# /Users/dennish/.rvm/gems/ruby-2.5.0/gems/turbolinks-5.1.0/lib/turbolinks/assertions.rb:37:in `turbolinks_request?'
# /Users/dennish/.rvm/gems/ruby-2.5.0/gems/turbolinks-5.1.0/lib/turbolinks/assertions.rb:6:in `assert_redirected_to'
# ./spec/requests/salesmen_spec.rb:206:in `block (3 levels) in <top (required)>'
This is the spec:
describe 'DELETE /salesman/:id' do
subject(:request) do
delete salesman_path(salesman), headers: auth_headers
end
let!(:salesman) { create :salesman }
it 'destroys salesman' do
expect { request }.to change { Salesman.count }.by(-1)
end
it 'redirects to index' do
expect(request).to redirect_to company_salesmen_path(salesman.company)
end
end
The root cause of this error is:
subject(:request)
By assigning :request we are overwriting rails internals - hence it breaks and the tests fail wierdly.
The Solution
Just go with the default (no name)
subject { delete salesman_path(salesman) }
Or you can rename the subject:
subject(:http_request) { delete salesman_path(salesman) }
Both solutions will make the tests succeed.
I had this same issue it seems to be a compatibility issue with Turbolinks 5.1 and Rails 5.0.x. Downgrading to Turbolinks 5.0.1 solved it for me.
By renaming the request to http_request is solving this.
Related
I updated the Ruby version from 2.7.3 to 3.2.0 in my project and some tests started to fail. Among those is one that is calling a function with keyword arguments. This is the error it's throwing:
1) NotificationsMailer notify Sets body
Failure/Error:
def notify(recipient_emails:, subject:, body:)
#body = body
#subject = subject
mail(bcc: recipient_emails, subject: #subject, reply_to: VENDOR_SUPPORT_EMAIL)
end
ArgumentError:
wrong number of arguments (given 1, expected 0; required keywords: recipient_emails, subject, body)
# ./app/mailers/notifications_mailer.rb:5:in `notify'
# /usr/local/bundle/gems/actiontext-6.1.6/lib/action_text/rendering.rb:20:in `with_renderer'
# /usr/local/bundle/gems/actiontext-6.1.6/lib/action_text/engine.rb:59:in `block (4 levels) in <class:Engine>'
# ./spec/mailers/notifications_mailer_spec.rb:16:in `block (3 levels) in <top (required)>'
This is the definition of the function being called:
class NotificationsMailer < ApplicationMailer
VENDOR_SUPPORT_EMAIL = "vendor-support#saatvamattress.com"
def notify(recipient_emails:, subject:, body:)
#body = body
#subject = subject
mail(bcc: recipient_emails, subject: #subject, reply_to: VENDOR_SUPPORT_EMAIL)
end
end
And this is the test file:
require "rails_helper"
RSpec.describe NotificationsMailer, type: :mailer do
describe 'notify' do
let(:recipient_emails) { %w[test#mail.com test2#mail.com] }
let(:mail) do
NotificationsMailer.notify(
recipient_emails: recipient_emails,
subject: 'subject',
body: 'body'
)
end
it 'Sets body' do
expect(mail.body.encoded).to match 'body'
end
it 'Sets subject' do
expect(mail.subject).to eq 'subject'
end
it "Does not set To" do
expect(mail.to).to be_nil
end
it "Does not set CC" do
expect(mail.cc).to be_nil
end
it "Sets BCC with recipients' emails" do
expect(mail.bcc).to eq ['test#mail.com', 'test2#mail.com']
end
it 'Sets reply_to with vendor support email' do
expect(mail.reply_to).to eq ['vendor-support#saatvamattress.com']
end
end
end
I know ruby 3 introduced some changes to keyword arguments, but as I'm calling the function with the arguments in the same order and specifying all the keywords, I don't see where my problem is.
Following some threads I tried sending the arguments in a hash and some other things that weren't so promising, but still getting the error, no clue of what's happening there.
I was able to reproduce your issue with Rails 6.1.7.2 and Ruby 3.2.1. The problem is that Rails 6.1 and Ruby 3.2 aren't fully compatible. There are efforts to backport 3.2 compatibility fixes to Rails 6.1 (see https://github.com/rails/rails/pull/46895) but they haven't been released yet it seems.
You could upgrade to a lower version of Ruby instead (3.1.2 worked fine for me, I'm sure 3.1.3 would too), or you could change your mailer code to be like this:
def notify(recipient_emails, subject, body)
[omitted]
end
(and obviously also change how you call that function).
There's some risk, though, that you'll run into more kwargs related issues with Rails 6.1 and Ruby 3.2, so maybe going with Ruby 3.1 is the better option.
Rails 6.1.3.1
Rspec
basic behavior spec code:
describe "index" do
it "should show me the list" do
visit dashboard_targets_path
end
end
the routes file
namespace :dashboard do
resources :targets
end
error shows me the exception, but strangely it appears as if it isn't calling through to the app, just fails right in my test code:
1) interaction for Dashboard::TargetsController index should show me the list
Failure/Error: visit dashboard_targets_path
NoMethodError:
undefined method `empty?' for nil:NilClass
# ./spec/system/dashboard/targets_behavior_spec.rb:16:in `block (3 levels) in <top (required)>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/webmock-3.12.2/lib/webmock/rspec.rb:37:in `block (2 levels) in <main>'
# /Users/jason/.rvm/gems/ruby-2.6.6/gems/rspec-wait-0.0.9/lib/rspec/wait.rb:46:in `block (2 levels) in <main>'
it seems to be failing inside the test code, if I drop into the debugger there and run dashboard_targets_path directly I also get the same exception, so the problem is just using the helper within the TEST ENVIRONMENT
within the dev environment, this function works
the problem here was the the config/environments/test.rb file does have default_url_options.
config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
when you hit errors that disappear into the Rails gems, a good way to debug them is like so:
begin
// your failing code here
rescue StandardError => e
puts e.backtrace
byebug
puts e.inspect
raise (e)
end
WARNING: do not leave this code in your app or check it in unless you explicitly want to use exception handling for flow control (not recommended!). This is recommended ONLY for debugging purposes.
here you will see the full backtrace to the line number in the Gem where it is failing. when debugging Gems be careful— remember to un-do any changes you make and know that your monkey-patching inside of the Gem code doesn't affect your production code.
I am using Rails 4.2.6, Ruby 2.2.1, rspec-rails 3.4.2, Grape 0.16.2, grape_token_auth 0.1.0. I installed apartment gem (1.0.2) for multitenancy and trying to write rspec tests for grape requests.
But I am getting the following error from rspec-rails response method every time irrespective of whatever solutions I tried.
#buf=["<!DOCTYPE html>\n<html>\n<head>\n <title>Apartment::TenantNotFound at /content/api/v1/questions</title>\n</head>\n<body>\n
The request is taking the host as 'www.example.com' all time. I tried so many solutions by googling it. But nothing works. you can see that in spec where I commented these lines. I want the url as 'http://g_m.lvh.me:3000' with the subdomain 'g_m'.
I tried this one:
https://github.com/influitive/apartment/wiki/Testing-Your-Application
But not works. I don't know why.
I tried this, but not working:
Rails: Wrong hostname for url helpers in rspec
and tried to set the host by:
host! "g_m.lvh.me:3000"
#request.host = 'g_m.lvh.me:3000'
request.host = 'g_m.lvh.me:3000'
Nothing works!
I created a test case like the following grape link says:
https://github.com/dblock/grape/commit/99bf4b44c511541c0e10f4506bf34ae9abcccd75
require 'rails_helper'
RSpec.describe ContentManager::QuestionAPI, :type => :request do
#before(:each) { Apartment::Tenant.switch!("g_m") }
#after(:each) { Apartment::Tenant.switch!("public") }
#before(:each) do
#begin
#client = FactoryGirl.create(:client, title: 'Sample title', subdomain: 'g_m')
#rescue
#client = Client.create!(title: 'Sample title', subdomain: 'g_m')
#end
#default_url_options[:host] = 'http://g_m.lvh.me:3000'
# request.host = "#{'g_m'}.lvh.me"
#end
#end
#before(:each) do
# if respond_to?(:default_url_options)
# default_url_options[:host] = 'http://g_m.lvh.me:3000'
# end
#end
describe "GET /content/api/v1/questions" do
it "returns an empty array of questions" do
get "/content/api/v1/questions"
#puts "response.inspect: #{response.inspect}"
response.status.should == 200
JSON.parse(response.body).should == []
end
end
end
My configurations:
in spec/rails_helper.rb
config.include RSpec::Rails::RequestExampleGroup, type: :request, file_path: /spec\/requests/
All time this request sent by rspec-rails with
url: '/content/api/v1/questions'
host: 'www.example.com'
My test result shows:
$ rspec spec/requests/
F
Failures:
1) ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
Failure/Error: response.status.should == 200
expected: 200
got: 500 (using ==)
# ./spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'
Deprecation Warnings:
Using `should` from rspec-expectations' old `:should` syntax without explicitly enabling the syntax is deprecated. Use the new `:expect` syntax or explicitly enable `:should` with `config.expect_with(:rspec) { |c| c.syntax = :should }` instead. Called from /home/vagrant/gauge-slcsl/spec/requests/question_spec.rb:30:in `block (3 levels) in <top (required)>'.
If you need more of the backtrace for any of these deprecations to
identify where to make the necessary changes, you can configure
`config.raise_errors_for_deprecations!`, and it will turn the
deprecation warnings into errors, giving you the full backtrace.
1 deprecation warning total
Finished in 6.19 seconds (files took 1.93 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/requests/question_spec.rb:26 # ContentManager::QuestionAPI GET /content/api/v1/questions returns an empty array of questions
abhi#ubuntu-trusty-64:~/my-app$
If anyone knows about the error and what I am doing wrong here, please reply/answer.
The error was because of, we have to say the apartment subdomain configuration that just exclude the 'www' word considering as a sub domain.
Add the following:
# config/initializers/apartment/subdomain_exclusions.rb
Apartment::Elevators::Subdomain.excluded_subdomains = ['www']
I was using the better_errors gem in my development and test environment. This causes the rspec output as an better error generated html codes and difficult to understand the rspec failure reason.
I removed better errors from 'test' environment and I got the clue of this error where we have to exclude the 'www' considering as a subdomain.
I’m trying to write some view specs that test some template logic. I’m following the instructions in the RSpec book, and also checking other online references. I don’t seem to have access to render or assign.
require "spec_helper"
describe "projects/index.html.erb" do
it "displays an entry for each project" do
projects = 5.times { FactoryGirl.create :project }
render
expect(all(".project-index-entry").count).to eq 5
end
end
When I run the above, I get:
Failure/Error: render
NameError:
undefined local variable or method `render' for #<RSpec::ExampleGroups::ProjectsIndexHtmlErb:0x007fa2950d4140>
# ./spec/views/projects/index.html.erb_spec.rb:7:in `block (2 levels) in <top (required)>'
The same thing happens if I try to use assign. I know I could use visit, but then I would have to simulate the act of the user signing in before each spec. I may be misunderstood, but I think the render method is meant to be more isolated, allowing me to skip the authentication check I have in the controller.
So, why don’t I have the view spec methods I was expecting?
Versions:
- capybara 2.4.1
- rails 4.1.0
- rspec-core 3.1.3
- rspec-expectations 3.1.1
- rspec-mocks 3.1.0
- rspec-rails 3.1.0
As it turns out, I updated rspec some time ago and the previous version used a significantly different spec_helper. After the update, the logic was split into spec_helper and rails_helper, so to fix this problem I had to rerun rails generate rspec:install.
I'm in the process of upgrading an old krufty application to Rails 3.1. The company has been using RSpec and Capybara for acceptance tests. We've got some acceptance tests under spec/acceptance that are failing with the following message:
Failure/Error: get #url
NoMethodError:
undefined method `get' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0x007feb7c0abf58>
Here's an example of one of the tests (from the top of the file):
require_relative 'acceptance_helper'
feature 'Catalog' do
before do
Settings.use_catalog_navigation = true
end
context 'with a Vendor' do
before do
#vendor = create(:vendor, slug: 'abc')
#product = create(:product_with_variants, vendor: #vendor)
#non_vendor_product = create(:product_with_variants)
#invisible_product = create(:product_with_variants,
vendor: #vendor,
visible: false)
#non_available_product = create(:product_with_variants,
vendor: #vendor,
available: false)
#url = "/#{#vendor.slug}"
end
it 'sets #vendor' do # <- FIRST FAILING TEST
get #url
assigns(:vendor).should == #vendor
end
...
When consulting the oracle, I keep stumbling across issues mentioning the 'visit' method such as this: https://github.com/jnicklas/capybara/issues/814
I also keep coming across posts related to this article: http://alindeman.github.com/2012/11/11/rspec-rails-and-capybara-2.0-what-you-need-to-know.html
I'm not sure that I'm having the same issue. I can post my spec_helper.rb and acceptance_helper.rb if they will be of any use.
I guess it's worth noting that these specs passed before I updated rspec-rails and capybara.
My gut feeling is that perhaps rspec-rails is clobbering some of capybara's methods, or some of capybara's methods are simply no longer being loaded. Could that be the issue?
Try and add config.include Capybara::DSL in spec_helper.rb, inside the config block. like so:
RSpec.configure do |config|
config.include Capybara::DSL