![](/img/trans.png)
[英]How do I test the assignment of an instance variable in the new action of my controller with rspec?
[英]How do I test an instance variable in a controller?
我的幾個導師告訴我使用 controller 規范測試一段代碼,即使某些請求規范正在測試內容。 我想知道是否可以在 rspec controller 測試中測試像@user
這樣的實例變量是否可以設置為someObject
或nil
?
到目前為止,我已經嘗試了幾種不同的方法來測試它,但我在 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.