Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capybara issue: @request must be an ActionDispatch::Request

I'm having problems making Capybara work with Rails. Just testing that suposedly interesting test thing. OK, in the attached code there are a couple of equivalent tests. The first one is made with shoulda-context + Test::Unit that comes with Rails. The second test is made 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 works OK, the capybara one throws 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 an accumulator of all suposed solutions I've found googling around and that don't 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

Has anybody a solution? Should I try another Integration frmawork such as webrat?

My setup is:

marcel@pua:~/Desenvolupament/Rails3Examples/ror_tutorial$ rake about
About your application's 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

Also

shoulda-context (1.0.0)
capybara (1.1.2)

Thanks

like image 581
marcel massana Avatar asked Dec 17 '22 04:12

marcel massana


1 Answers

You're mixing up your test types and attempting to assert a template in the wrong type of test. You should only be asserting templates within your Functional tests, where you're just directly testing a controller and not actually simulating a user interaction.

Capybara is meant specifically for Integration testing, which is essentially running tests from the viewpoint of an end-user interacting with a browser. In these tests, you should not be asserting templates because an end-user can't see that deep into your application. What you should instead be testing is that an action lands you on the correct path.

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

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

Official explanation for your issue: https://github.com/jnicklas/capybara/issues/240

like image 155
Ryan Avatar answered May 14 '23 02:05

Ryan