7

我一直对此低头,觉得我可能犯了一个简单的错误,但我无法找到关于这个问题的任何信息。

我有一些 Rails 5 的请求规范,当我测试重定向时——但不是渲染模板——我得到一个错误,undefined method 'response_code' for nil:NilClass. 原因似乎@responsenil在调用匹配器时(在 ActionDispatch::Assertions::ResponseAssertions 代码中,而不是在我的代码中)。我可以使用 cURL 向 API 发出请求,它会按预期返回响应。返回错误的地方在这里(这是 ActionDispatch 代码):

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

请注意第一行,其中actual参数的默认值设置为@response.response_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

测试日志中的相关行是:

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)

有趣的是,当我使用 byebug 检查 的值时subject,它确实返回了一个 Rack::MockResponse 对象,所以这在某种程度上没有通过。

非常感谢我能得到的任何帮助!

4

2 回答 2

2

我确定您可能已经解决了这个问题,但是对于可能偶然发现此问题的其他任何人,我们遇到了同样的事情(response在提出请求方式后没有被分配 - 要么 要么getpost没有尝试其他方法,但假设它们都是一样的)。一直在工作的现有请求规范都开始失败。

在我们的案例中,罪魁祸首被追查到 中所需的模块rails_helper.rb,并添加到 rspec 的config.include列表中:

config.include ApiHelper, type: request

里面AppHelper是根本原因:

include Rack::Test::Methods

注释掉这条线(最终对我们来说,删除整个帮助器,因为它并不是真正需要的)将请求规范恢复到它们以前的工作状态。

tl;博士:

确保您不会无意中包含Rack::Test::Methodsconfig.include您的 rspec 配置中。

于 2018-12-06T02:10:06.513 回答
0

这对我来说很愚蠢,但我敢打赌别人或我自己会意外地这样做。

如果type: :request已在您的顶部块中设置,还要确保您不会意外覆盖response块中的变量。

以我愚蠢的自我为例作为警告:

let(:response) { }

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

结果如下:

Error: nil doesn't have property 'status'

那是因为let(:response)rspec 实际上覆盖了 rspec 自己的 internal response

只是要记住一些事情,你可能永远不会像这样搞砸,但以防万一。

于 2020-10-09T16:59:32.790 回答