Capybara problem: @request must be ActionDispatch :: Request

I have problems with Capybara with Rails. Just checking that this is probably an interesting test thing. Well, there are some equivalent tests in the attached code. The first one is done using the toa-context + Test :: Unit command, which comes with Rails. The second test runs with capybara and shoulda-context too.

require 'integration_test_helper' class UsersTest < ActionDispatch::IntegrationTest fixtures :all context "signup" do context "failure" do setup do @attr = { :name => "", :email => "", :password => "", :password_confirmation => "" } end should "not make a new user" do assert_no_difference 'User.count' do post_via_redirect "users", :user =>@attr # enviem les dades d'un nou usuari via create (POST /users) assert_template 'users/new' # ens retorna a users/new, que significa que no s'ha creat l'usuari assert_select "div#error_explanation" # comprovem que conte missatges d'error end end should "not make a new user (capybara)" do assert_no_difference 'User.count' do visit '/signup' fill_in 'Name', :with => @attr[:name] fill_in 'Email', :with => @attr[:email] fill_in 'Password', :with => @attr[:password] fill_in 'Confirmation', :with => @attr[:password_confirmation] click_button 'Sign Up!' assert_template 'users/new' # ens retorna a users/new, que significa que no s'ha creat l'usuari assert_select "div#error_explanation" # comprovem que conte missatges d'error end end end end 

While the first one is working fine, capybara gives this error message:

 ================================================================================ Error: test: signup failure should not make a new user (capybara). (UsersTest): ArgumentError: @request must be an ActionDispatch::Request test/integration/users_test.rb:30:in `block (4 levels) in <class:UsersTest>' test/integration/users_test.rb:23:in `block (3 levels) in <class:UsersTest>' ================================================================================ 

the required * integration_test_helper.rb * file is the accumulator of all the allowed solutions that I found on Google, and this does not work for me.

 require 'test_helper' require 'capybara/rails' require 'database_cleaner' # Transactional fixtures do not work with Selenium tests, because Capybara # uses a separate server thread, which the transactions would be hidden # from. We hence use DatabaseCleaner to truncate our test database. DatabaseCleaner.strategy = :truncation class ActionDispatch::IntegrationTest # Make the Capybara DSL available in all integration tests include Capybara::DSL # Stop ActiveRecord from wrapping tests in transactions self.use_transactional_fixtures = false teardown do DatabaseCleaner.clean # Truncate the database Capybara.reset_sessions! # Forget the (simulated) browser state Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver end end 

Does anyone have a solution? Should I try another integration frmawork like webrat?

My setup:

 marcel@pua :~/Desenvolupament/Rails3Examples/ror_tutorial$ rake about About your application environment Ruby version 1.9.2 (x86_64-linux) RubyGems version 1.8.15 Rack version 1.3 Rails version 3.1.3 JavaScript Runtime therubyracer (V8) Active Record version 3.1.3 Action Pack version 3.1.3 Active Resource version 3.1.3 Action Mailer version 3.1.3 Active Support version 3.1.3 Middleware ActionDispatch::Static, Rack::Lock, #<ActiveSupport::Cache::Strategy::LocalCache::Middleware:0x00000002b9bac0>, Rack::Runtime, Rack::MethodOverride, Rails::Rack::Logger, ActionDispatch::ShowExceptions, ActionDispatch::RemoteIp, Rack::Sendfile, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::ConnectionAdapters::ConnectionManagement, ActiveRecord::QueryCache, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ParamsParser, ActionDispatch::Head, Rack::ConditionalGet, Rack::ETag, ActionDispatch::BestStandardsSupport Application root /mnt/dropbox/Dropbox/DESENVOLUPAMENT/Rails3Examples/ror_tutorial Environment development Database adapter sqlite3 Database schema version 20120127011330 

Besides

 shoulda-context (1.0.0) capybara (1.1.2) 

thanks

+4
source share
3 answers

You mix your test types and try to validate the template in the wrong test type. You should only approve the templates in your functional tests, where you simply directly test the controller and do not imitate user interaction.

Capybara is specifically designed for integration testing, which essentially runs tests in terms of end-user interaction with the browser. In these tests, you should not approve the patterns because the end user cannot see this deep in your application. What you should test is that the action leads you on the right path.

 current_path.should == new_user_path page.should have_selector('div#error_explanation') 

See the "DSL" section in Capybara README on git: https://github.com/jnicklas/capybara

An official explanation of your problem: https://github.com/jnicklas/capybara/issues/240

+11
source

For my completeness, because I will know that I will return to this link again:

Those who use the test unit and capybara are a good primer: from techiferous .

Note the use of assert page.has_content?("something")

This is useful to use, as well as assert_equal some_path, current_path for testing routes.

It is the most complete, I do not know, but you do not need much more.

+1
source

Thanks for the advice @Ryan. I tried to figure out how to translate some sample RSpec integration tests from http://ruby.railstutorial.org/chapters/sign-up#sec:rspec_integration_tests into Test :: Unit + Capybara. RSpec's initial integration test was

 it "should not make a new user" do lambda do visit signup_path fill_in "Name", :with => "" fill_in "Email", :with => "" fill_in "Password", :with => "" fill_in "Confirmation", :with => "" click_button response.should render_template('users/new') response.should have_selector("div#error_explanation") end.should_not change(User, :count) end end 

So, after your answer, I believe that the original example should not contain response.should render_template('users/new')

0
source

Source: https://habr.com/ru/post/1394303/


All Articles