I am upgrading from rails 3.2.19 to rails 4.1.5. I am using rspec-rails 2.14.0.rc1.
With rails 4.1.5 all my tests are passing, except for a handful that use stub. The ones that are failing are of the form:
ENV.stub(:[]).with("ADWORDS_RUN").and_return("Yes")
Rails.stub(env: ActiveSupport::StringInquirer.new("production"))
Kernel.stub(:rand).and_return(2)
Each is returning ArgumentError: wrong number of arguments (1 for 2+). All were passing in rails 3.2.19. I have tried going back to rspec-rails 2.8.1, but same error. Also rails 4.0, but the error persists. The last error (stubbing :rand) does not occur when I run the whole test suite but does occur when I run the individual test file for that test. Here is an example test
it "should have google tracking code in production" do
Rails.stub(env: ActiveSupport::StringInquirer.new("production"))
get :home
response.body.should =~ /Google Analytics Tracking code/
end
and here is the output from the test:
Failure/Error: Rails.stub(env: ActiveSupport::StringInquirer.new("production"))
ArgumentError:
wrong number of arguments (1 for 2+)
# ./spec/controllers/pages_controller_spec.rb:107:in `block (4 levels) in <top (required)>'
Line 107 is the Rails.stub line.
Please let me know how to rectify this problem?
I did not manage to find the cause of this problem, but I did find a workaround. It was to change all the stub statements to the newer rspec allow syntax. So for example
Rails.stub(env: ActiveSupport::StringInquirer.new("production"))
becomes
allow(Rails).to receive(:env).and_return(ActiveSupport::StringInquirer.new("production"))
I did this using rspec-rails 2.14.0.rc1. This fixed the problem.
Thank you for the comments, they either clarified my question or pointed me in the right direction.
Related
Recently my tests are started failing with following exception.
NoMethodError:
undefined method `and' for #<Capybara::RSpecMatchers::Matchers::HaveText:0x00007f97687dbe30>
Did you mean? end
My tests looks like
it "starts german but allows to be changed to english" do
within(".e-header") do
# german locale
expect(page).to have_content("Mein Anliegen").and not_have_content("My issue")
end
end
Rspec 3.10 documentation for compound expectations still supporting it. I am not sure why suddenly my tests started failing.
it looks like capybara will not include compound module if rspec expectations is not be defined (in other words, not require yet)
so try require "rspec/expectations" explicitly.
the reason:
it was due to the version range of RSpec we supported combined with the fact that a few people complained when we did because some people didn't want RSpec::Expectations. Most people don't run into this issue because they're using Capybara with rspec-rails.
A very similar error happened when I ran my test suite with Spring enabled:
undefined method `and' for #<Capybara::RSpecMatchers::Matchers::HaveSelector
The answer in the comment by Asad Ali helped, just added:
bundle add rspec-expectations --group test
And the specs work with Spring.
I've created a Rails 4 app with a mountable Rails 4 engine called Foobar. That engine contains a scaffold for Items.
After setting up rspec-rails in the engine, I am unable to get the view specs to pass.
I get the following error:
2) foobar/items/index renders a list of items
Failure/Error: render
ActionView::Template::Error:
undefined method `item_path' for #<#<Class:0x007fe6dae7b3c8>:0x007fe6da9a2ec8>
# ./app/views/foobar/items/index.html.erb:21:in `block in ___sers_ianneub__ocuments__ode_rails_engine_spec_test_engines_foobar_app_views_foobar_items_index_html_erb__1719273292435665376_70314743713380'
# ./app/views/foobar/items/index.html.erb:16:in `each'
# ./app/views/foobar/items/index.html.erb:16:in `___sers_ianneub__ocuments__ode_rails_engine_spec_test_engines_foobar_app_views_foobar_items_index_html_erb__1719273292435665376_70314743713380'
# ./spec/views/foobar/items/index.html.erb_spec.rb:20:in `block (2 levels) in <top (required)>'
When starting up the rails server in either the outer application or the engine's spec/dummy app the views all seem to work just fine.
So my question is:
Why do the rspec tests fail, even though the engine views work fine from the rails server?
Bonus question:
What can I change in the index.html.erb to make the test pass?
I'm really trying to understand what is at play here in the rspec tests. IMHO it seems like there is an issue with rspec (and/or rspec-rails) that prevents this from working. Like something isn't being loaded in the tests that would normally make this work inside the rails server. In other words: if it works in the rails server, then it should work in rspec the same way. Would that be correct? What am I missing?
The app is available here:
https://github.com/ianneub/rails-engine-spec-test
You should be able to clone the repo and run these commands to duplicate the error:
cd engines/foobar
bundle install
rspec
Thank you in advance for any help and guidance that you share with me (and the world).
Line 21 in the 'index.html.erb' view needs scoping to the foobar gem.
<td><%= link_to 'Show', foobar.item_path(item) %></td>
That's because Rspec renderer do not include url_helpers methods, but rails renderer somehow included these methods. Could be fixed by
a before hook:
RSpec.configure do |config|
config.before(:example, type: :view) do
view.class_eval do
include <Your Engine Namespace>::Engine.routes.url_helpers
end
end
end
Not quite sure what's going on here. I'm moving over some code from another project of mine and suddenly the same specs from before are generating errors in the new project. All the errors appear to revolve around calling the stub method. Here's an example test:
it "retrieves active workers from Redis" do
#monitor.should_receive(:monitor_running?).and_return(false)
REDIS.should_receive( :smembers ).with( 'leaderboard-workers' ).and_return( [] )
#monitor.perform
end
This works. However if I switch the first test line to this:
#monitor.stub(:monitor_running?).and_return(false)
I end up with the following error:
1) LeaderboardMonitor#perform retrieves active workers from Redis
Failure/Error: #monitor.stub(:monitor_running?).and_return(false)
Mocha::ExpectationError:
unexpected invocation: #<Mock:0x7fcc18c8bab8>.and_return(false)
satisfied expectations:
- allowed any number of times, not yet invoked: #<Mock:0x7fcc18c8bab8>.monitor_running?(any_parameters)
# ./spec/workers/leaderboards/leaderboard_monitor_spec.rb:58:in `block (3 levels) in <top (required)>'
I'm not quite sure what's going on here. Is this an issue with Mocha overriding the stub method? How do I work around this?!?!?
I don't know what version of mocha you are using. Have you tried something like
#monitor.expects(:monitor_running?).returns(false).at_least_once
I'm trudging through this deeply error-prone tutorial on Ruby on Rails located here: http://ruby.railstutorial.org/ruby-on-rails-tutorial-book.
I've been working through a section about testing using rspec. Now, the instructions that this tutorial provided created a whole host of errors (deprecations, array issues, etc.) that filled up my page. After rummaging the internet for several hours, I decided to follow several suggestions to update all my gems.
Having updated my gems and attempted to perform this very basic test (the default test really), I got this whole pile of error that I couldn't begin to understand. All I can say is "please help".
Thank you.
> bundle exec rspec spec/requests/static_pages_spec.rb
Rack::File headers parameter replaces cache_control after Rack 1.5.
←[31mF←[0m
Failures:
1) StaticPages GET /static_pages works! (now write some real specs)
←[31mFailure/Error:←[0m ←[31mget static_pages_path←[0m
←[31mNameError:←[0m
←[31mundefined local variable or method `static_pages_path' for #<RSpec::
Core::ExampleGroup::Nested_1::Nested_1:0x5168040>←[0m
←[36m # ./spec/requests/static_pages_spec.rb:6:in `block (3 levels) in <top
(required)>'←[0m
Finished in 0.19901 seconds
←[31m1 example, 1 failure←[0m
Failed examples:
←[31mrspec ./spec/requests/static_pages_spec.rb:5←[0m ←[36m# StaticPages GET /st
atic_pages works! (now write some real specs)←[0m
If you upgraded all your gems to the latest, then one issue you probably have is your newer capybara gem no longer looks for your tests in 'spec/requests'. That test needs to be in 'spec/features' now. If there is no 'spec/features' just create it.
Also, capybara will need this line in your 'spec/spec_helper.rb' if it isn't already:
require 'capybara/rspec'
So, I'm getting a pretty strange error here... I tried to isolate it but it's quasi-intermittent. I'm kinda wondering if it has something to do with using capybara with a javascript driver, because this isn't happening in my non-capybara tests. Here it is:
Failure/Error: #existing_user, household = create_new_user_and_household
ActiveRecord::AssociationTypeMismatch:
User(#57141560) expected, got User(#42098260)
# ./app/models/household.rb:64:in `block in create_new_household'
# ./app/models/household.rb:62:in `new'
# ./app/models/household.rb:62:in `create_new_household'
# ./spec/support/spec_helpers.rb:55:in `create_new_user_and_household'
# ./spec/integration/accepting_an_invitation_spec.rb:21:in `block (4 levels) in <top (required)>'
Here's the block in question:
household = Household.new attributes, do |h|
h.account = user.account || Account.create(user: user)
end
Pretty basic, and works fine when I do it manually in the rails console.
I'm not sure what else to tell you guys... but I'm happy to provide more info.
I'm using rspec for all of my testing.
So the answer, as Frederick Cheung pointed out was to set cache_classes to true in test.rb.
This supposedly conflicts with spork, which is why I was told to turn it off in the first place--since you want spork to re-load your models and whatnot whenever you run another test. The solution is to set cache_classes to true but also put ActiveSupport::Dependencies.clear in your spork prefork block.
References:
ActiveSupport:Dependencies
Reloading Models
Spork tips
Spork cache_classes explanation