为什么控制器应该测试 allocate_to 无法访问实例变量?
对于我的 Rails 3 应用程序,我将 FactoryGirl 与 Shoulda 上下文 (1.0.0.beta1) 和匹配器 (1.0.0.beta3) 一起使用来进行功能测试。 我的问题:在下面的代码示例中, allocate_to 测试失败,因为 @user - 令我惊讶的是 - 结果为零。在外部设置块中,@user 被分配了一个有效的模型实例,但从should allocate_to 语句中无法访问实例变量。这是为什么?编写该测试的正确方法是什么?
class UsersControllerTest < ActionController::TestCase
context "as admin" do
setup do
@user = Factory.create(:user)
end
context "getting index" do
setup do
get :index
end
should assign_to(:users).with([@user])
end
end
For my Rails 3 application I use FactoryGirl together with shoulda context (1.0.0.beta1) and matchers (1.0.0.beta3) for my functional tests.
My problem: in the code example below, the assign_to test fails because @user - to my surprise - turns out to be nil. In the outer setup block, @user is assigned a valid model instance, but from within the should assign_to statement the instance variable is not accessible. Why is that and what is the correct way to write that test?
class UsersControllerTest < ActionController::TestCase
context "as admin" do
setup do
@user = Factory.create(:user)
end
context "getting index" do
setup do
get :index
end
should assign_to(:users).with([@user])
end
end
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我发现以黑人的身份传递价值奇迹般地有效。但是,在深入研究实际的 AssignToMatcher 代码之后,为什么参数方法不起作用而块方法却起作用,这似乎没有意义。
为了获得 +250 代表,我对此进行了投资,我仍然想要一个答案来解释为什么 param 方法不起作用(以及如何修复它),但在那之前,至少我有一个解决方法。
@dblp1,希望这也适合你。这是一个特定于您的代码的示例:
I discovered that passing the value as a black miraculously works. However, after digging into the actual AssignToMatcher code, it doesn't seem to make sense why the parameter method wouldn't work while the block method would.
For the sake of the +250 rep I'm investing in this, I'd still like an answer that explains why the param method isn't working (and how to fix it), but until then, at least I have a workaround.
@dblp1, hopefully this works for you too. Here's an example specific to your code:
(我粘贴作为答案,因为它相当长)
我嘲笑了你的测试并检查了通过的结果。
有趣的是,当我调用匹配器
@post=null
(正如我相信你的情况一样)。我认为的问题(经过一段时间的调查),它来自于 setup do 块的调用顺序以及在一个上下文中定义的变量在嵌套上下文中不可见的事实。修改后的类
和控制台中的结果
因此,设置周期在结束时(而不是在开始时)被调用,然后当传递给匹配器时,您的值为 Nil 。
即使我删除第一个
setup
也不能很好地工作。最后,将帖子放在内部上下文中
如果您直接在“获取索引”上下文中调用
@user = Factory.create(:user)
,我相信它会起作用。(I am pasting as an answer as it is fairly long)
I mocked a bit your test and checked what was the results passed.
Interestingly enough, when I call the matcher
@post=null
(as I believe in your case). The issues I think (after a while of investigation), it coming from the the order thesetup do
block is called and the fact that the variables defined in one context are not visible in the nested context.modified class
And the results in the console
So the setup cycle is called at the end (and not at the beginning) and then your is Nil when passed to the matcher.
Even if I remove the first
setup do
does not work pretty well.Finally, putting the post in the inner context
If you call
@user = Factory.create(:user)
directly inside the "getting index" context, I believe it will work.当您使用索引时,您应该使用实例变量的复数。
@users
而不是@user
您还应该将其填充为数组。
最后,应该匹配器应该以“it”开头并包含在大括号中,至少在我使用的 RSpec 世界中是这样。不确定 Test::Unit 是否属于这种情况,或者您上面的格式是否有效。
尝试这样的事情。
When you are working with indexes you should use the plural of the instance variable.
@users
rather than@user
You should also populate it as an array.
Finally, Shoulda matchers should start with "it" and be contained in braces, at least in the RSpec world, which is what I use. Not sure if this is the case with Test::Unit or whether your formatting above will work.
Try something like this.