簡體   English   中英

如何測試 controller 中的實例變量?

[英]How do I test an instance variable in a controller?

我的幾個導師告訴我使用 controller 規范測試一段代碼,即使某些請求規范正在測試內容。 我想知道是否可以在 rspec controller 測試中測試像@user這樣的實例變量是否可以設置為someObjectnil

到目前為止,我已經嘗試了幾種不同的方法來測試它,但我在 rspec 測試方面的技能至少可以說是初級的。 我嘗試的第一件事是 mocking 輸出 current_user 和 'User.get_from_auth_user(current_user)。 模擬的 object 打印良好並輸出。 問題是......我希望能夠說類似expect(@user).to equal(mockedUser)但這似乎永遠不會奏效。 我總是得到類似的東西:

Expect does not equal received
expected is nil
received is { someMockedObject }

這是我要測試的代碼。

class ApplicationController < ActionController::Base
  before_action :set_user

  def set_user
    return if current_user.nil?

    @user = User.get_from_auth_user(current_user)
  end
end

我想知道我是否走在正確的道路上,或者什么是完全測試這段代碼的更好選擇。 我覺得答案應該很簡單。

你的導師很愚蠢。 雖然了解 controller 規范可能會很好,因為它們在舊應用程序中無處不在,但將它們添加到新應用程序並不是一個好習慣。

對於新的 Rails 應用程序:我們不建議將 rails-controller-testing gem 添加到您的應用程序中。 Rails 團隊和 RSpec 核心團隊的官方建議是改為編寫請求規范。 請求規范允許您專注於單個 controller 操作,但與 controller 不同的是,測試涉及路由器、中間件堆棧以及機架請求和響應。 這增加了您正在編寫的測試的真實性,並有助於避免 controller 規范中常見的許多問題。

DHH 很好地解釋了測試 controller 的實例變量有什么問題以及您應該做什么:

測試您的 controller 設置了哪些實例變量是一個壞主意。 這嚴重超出了測試應該知道的范圍。 您可以測試設置了什么 cookies,返回什么 HTTP 代碼,視圖的外觀,或者數據庫發生了什么突變,但是測試 controller 的內部結構並不是一個好主意。

這就是為什么assigns提取到單獨的 gem 的原因。 這一切都歸結為測試你的代碼做了什么——而不是它是怎么做的。

看:

使用 assigns assigns(:user)獲取實例變量@user 在您的規范中, @user是該測試上下文中的一個變量,它與@user中的 @user 不同。

https://relishapp.com/rspec/rspec-rails/docs/controller-specs

除了@chans@arieljuod 的答案,值得一提的是,為了在您的規范中使用assigns ,您需要設置rails-controller-testing gem,因為從 Rails 5 開始不推薦使用assigns

# File actionpack/lib/action_dispatch/testing/test_process.rb, line 6
def assigns(key = nil)
  raise NoMethodError,
    "assigns has been extracted to a gem. To continue using it,
    add `gem 'rails-controller-testing'` to your Gemfile."
end

controller 測試用例如下所示

describe 'GET #set_user' do
  let!(:mock_user) { 
      @mockuserObj = { id: 1, name: "username" }
  }
  before(:each) do
    controller.instance_variable_set(:current_user, @mockuserObj)
    get :set_user
  end
  context 'when current_user is present' do
    it "sets the current user" do
      expect(assigns(:user)).to eq(@mockuserObj)
    end
  end
end

暫無
暫無

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

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