Agile Web Development With Rails4 gives an example test code like this:
carts_controller_test.rb:
test "should destroy cart" do
assert_difference('Cart.count', -1) do
session[:cart_id] = @cart.id
...
However, when I try this in rails 5
>>rake test
an error is raised
NoMethodError: undefined method `session' for nil:NilClass
How to use session in the test controller in rails 5? Or did I overlook some important config?
The currently accepted way to test rails controllers is by sending http requests to your application and writing assertions about the response. Rails has ActionDispatch::IntegrationTest which provides integration tests for Minitest which is the Ruby standard library testing framework.
We can run all of our tests at once by using the bin/rails test command. Or we can run a single test file by passing the bin/rails test command the filename containing the test cases. This will run all test methods from the test case.
Rails session is only available in controller or view and can use different storage mechanisms. It is a place to store data from first request that can be read from later requests. Following are some storage mechanism for sessions in Rails: ActionDispatch::Session::CookieStore - Stores everything on the client.
Most methods can be tested by saying, “When I pass in argument X, I expect return value Y.” This one isn't so straightforward though. This is more like “When the user sees output X and then enters value V, expect subsequent output O.” Instead of accepting arguments, this method gets its value from user input.
In Rails 5 it is no longer possible to access session in controller tests: http://blog.napcs.com/2016/07/03/upgrading-rails-5-controller-tests/. The suggestion is to access the controller method that would set the appropriate session value for you. This comment shows and example of how you might work around this limitation: https://github.com/rails/rails/issues/23386#issuecomment-192954569
# helper method
def sign_in_as(name)
post login_url, params: { sig: users(name).perishable_signature )
end
class SomeControllerTest
setup { sign_in_as 'david' }
test 'the truth' do
..
I have found the answer in the Unable to set session hash in Rails 5 controller test
Test controllers of rails5 inherit from ActionDispatch::IntegrationTest by default while rails4 from ActionController::TestCase. Session is not available in the context of ActionDispatch::IntegrationTest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With