簡體   English   中英

Rails 5集成測試失敗,出現NoMethodError:使用Devise helper sign_in時nil:NilClass的未定義方法'[] ='

[英]Rails 5 Integration test fails with NoMethodError: undefined method `[]=' for nil:NilClass when using Devise helper sign_in

我正在使用內置的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行之前調試marty變量。 它顯示了相關(夾具)記錄的預期小狗數組。

我還在控制器動作的最頂部放置了一個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),但是我不知道如何在錯誤不會給我任何上下文的情況下進行跟蹤。

UPDATE

我已將此問題隔離為使用Devise幫助程序sign_in方法。 當我刪除此方法調用時,問題就消失了。

這是有問題的測試類:

require 'test_helper'

class PuppiesEndpointsTest < ActionDispatch::IntegrationTest

    include Devise::Test::IntegrationHelpers

    test "do stuff" do
       ...

應用程序/控制器/ api_controller.rb:

class ApiController < ActionController::API
end

也許sign_in不適用於未從ActionController :: Base繼承的測試控制器

我將控制器更改為從ActionController::Base繼承,並且沒有任何更改。 我仍然無法sign_in沒有收到該錯誤的情況下使用sign_in ,但是它可以找到是否“我”將請求“手動” post到sign_in端點。

更新2我發現這個Devise問題聽起來與我的問題有關: https : //github.com/plataformatec/devise/issues/2065

看來我找到了問題 顯然,在rails-api模式下,將ActionDispatch :: Cookies和ActionDispatch :: Session :: CookieStore中間件插入中間件堆棧的末尾,這在正常的Rails模式下不會發生。

因此,這些中間件被包含在Warden :: Manager之后,該中間件弄亂了請求規范中的某些內容。

嘗試在test.rb中設置

Rails.application.config.middleware.insert_before Warden::Manager, ActionDispatch::Cookies
Rails.application.config.middleware.insert_before Warden::Manager, ActionDispatch::Session::CookieStore

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM