简体   繁体   中英

nil response object in Rails 5.2, RSpec-Rails 3.7 spec for GET request

I've been heads down in this and feel like I'm probably making a simple mistake, but I haven't been able to find any information on this problem.

I have some request specs for Rails 5 and, when I test for a redirect--but not for a rendered template--I get an error, undefined method 'response_code' for nil:NilClass . The reason for this seems to be that @response is nil when the matcher is called (inside ActionDispatch::Assertions::ResponseAssertions code, not in my code). I am able to use cURL to make a request to the API and it returns a response as expected. The point where the error is returned is here (this is the ActionDispatch code):

def generate_response_message(expected, actual = @response.response_code)
  "Expected response to be a <#{code_with_name(expected)}>,"\
  " but was a <#{code_with_name(actual)}>"
  .dup.concat(location_if_redirected).concat(response_body_if_short)
end

Notice the first line, where the default value of the actual param is set to @response.response_code .

Here's my test code:

RSpec.describe "Admin registrations", type: :request do
  describe "new sign-up" do
    subject { get new_admin_registration_path }

    it "redirects to home" do
       expect(subject).to redirect_to(new_admin_session_path)
    end
  end
end

The relevant lines in the test log are:

Started GET "/admins/sign_up" for 127.0.0.1 at 2018-07-05 10:44:05 -0700
Processing by Admins::RegistrationsController#new as HTML
Redirected to http://example.org/admins/sign_in
Completed 301 Moved Permanently in 18ms (ActiveRecord: 0.0ms)

Interestingly, when I use byebug to check the value of subject , it does return a Rack::MockResponse object, so this is somehow not getting passed through.

Any help I can get with this is much appreciated!

I'm sure you've probably already solved this, but for anyone else who might stumble upon this, we ran into the same thing ( response not being assigned after a request way made - either get or post , didn't try other methods, but assume they would all be the same). Existing request specs that had been working all started failing.

The culprit in our case was tracked down to a module that was required in rails_helper.rb , and added to rspec's config.include list:

config.include ApiHelper, type: request

Inside AppHelper was the root cause:

include Rack::Test::Methods

Commenting that line out (and ultimately for us, removing the entire helper as it wasn't really needed) restored the request specs to their previous, and working, state.

tl;dr:

Make sure you're not including Rack::Test::Methods in config.include for your rspec config inadvertently.

This is pretty dumb on my part but I bet someone else or myself is going to do this by accident.

If type: :request is already set in your top block, also make sure you're not accidentally overriding the response variable in your block.

Take my dumb self's example as a warning:

let(:response) { }

it 'overrides rspec\'s own dediciated response variable' do
   get your_route_here_path
   expect(response).to have_http_status(:ok)
end

results in something like:

Error: nil doesn't have property 'status'

That's because the let(:response) is actually overriding rspec's own internal response .

Just something to keep in mind, you'll probably never screw up like this but just in case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM