我正在使用内置的Minitest编写Rails v5.1的集成测试。
这是集成测试类:
require 'test_helper'
class PuppiesEndpointsTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
test "DELETE puppy" do
marty = people(:marty)
sign_in(marty)
# delete puppies_delete_path(marty.puppies.first.id)
# delete `/api/v1/puppies/destroy/${marty.puppies.first.id}.json`
# delete puppies_path(marty.puppies.first.id)
delete '/api/v1/puppies/destroy/6666.json'
assert_response :success
end
end
以上所有路由,包括被注释掉的路由,都会导致相同的隐秘错误:
Error:
PuppiesEndpointsTest#test_DELETE_puppy:
NoMethodError: undefined method `[]=' for nil:NilClass
test/integration/puppies_endpoints_test.rb:17:in `block in <class:PuppiesEndpointsTest>'
bin/rails test test/integration/puppies_endpoints_test.rb:7
它不提供堆栈跟踪或任何其他信息来诊断它在说什么。我使用了byebug在抛出错误的marty
行之前调试了delete
变量。它显示了相关(夹具)记录的预期小狗数组。
我还在控制器动作的最顶部放置了一个byebug,并且该错误在到达该byebug之前未能通过测试,因此我认为动作代码中的所有内容都可以排除。
这是我运行rake routes
时看到的相关内容:
PATCH /api/v1/puppies/edit/:id(.:format) puppies#update
DELETE /api/v1/puppies/destroy/:id(.:format) puppies#destroy
puppies_create POST /api/v1/puppies/create(.:format) puppies#create
这是我的路线文件中的实际内容:
scope '/api' do
scope '/v1' do
devise_for :people
patch 'puppies/edit/:id' => 'puppies#update'
delete 'puppies/destroy/:id' => 'puppies#destroy'#, as: 'puppies_delete'
post 'puppies/create' => 'puppies#create'
...
我完全困惑为什么/为什么收到此错误。实际的代码完全可以按预期工作。
我的直觉是,也许有一个缺少的配置变量没有为测试环境设置(我使用dotenv gem),但是我不知道如何在错误不会给我任何上下文的情况下进行跟踪。
更新
我已将此问题隔离为使用Devise帮助器sign_in
方法。当我删除此方法调用时,问题就消失了。
这是有问题的测试班:
require 'test_helper'
class PuppiesEndpointsTest < ActionDispatch::IntegrationTest
include Devise::Test::IntegrationHelpers
test "do stuff" do
...
app / controllers / api_controller.rb:
class ApiController < ActionController::API
end
也许 sign_in
不适用于未从ActionController :: Base
我将控制器更改为从ActionController::Base
继承,没有任何更改。我仍然无法使用sign_in
而不出现该错误,但是可以找到我是否“手动” post
对sign_in端点的请求。
更新2 我发现了这个与我的问题有关的Devise问题:https://github.com/plataformatec/devise/issues/2065
答案 0 :(得分:1)
好像我找到了issue。显然,在rails-api模式下,将ActionDispatch :: Cookies和ActionDispatch :: Session :: CookieStore中间件插入中间件堆栈的末尾,这在正常的Rails模式下不会发生。
由于这个原因,那些中间件包含在Warden :: Manager之后,该中间件弄乱了请求规范中的某些内容。
尝试在test.rb中设置
layout = dict(yaxis=dict(title="Percents values",
# Choose what you want to see on yaxis! In this case list
tickvals=[i for i in range(len(percentage_difference))],
ticktext=percentage_difference
)
)