![](/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.