指定明确的“主题”时遇到麻烦?
我正在使用 Ruby on Rails 3.0.9 和 RSpect 2。我尝试按以下方式重构一些规范文件(以便使用更少的代码进行类似 User
类对象属性值的测试):
describe User do
let(:user1) { Factory(:user, :users_attribute_a => 'invalid_value') }
let(:user2) { Factory(:user, :users_attribute_b => 'invalid_value') }
let(:user3) { Factory(:user, :users_attribute_c => 'invalid_value') }
it "foreach user" do
[ user1, user2, user3 ].each do |user|
subject { user }
it "should be whatever"
user.should_not be_valid
...
end
end
end
end
但是,如果我运行上述测试,我会收到以下错误:
Failure/Error: it "should be whatever" do
NoMethodError:
undefined method `it' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_2::Nested_2:0x00000106ccee60>
问题是什么?我该如何解决这个问题?
在@Emily回答后更新。
如果在上面的代码中我使用 context "foreach user" do ...
而不是 it "foreach user" do ...
我收到以下错误:
undefined local variable or method `user1' for #<Class:0x00000105310758> (NameError)
I am using Ruby on Rails 3.0.9 and RSpect 2. I am trying to refactoring some spec file in the following way (in order to test with less code similar User
class object attribute values):
describe User do
let(:user1) { Factory(:user, :users_attribute_a => 'invalid_value') }
let(:user2) { Factory(:user, :users_attribute_b => 'invalid_value') }
let(:user3) { Factory(:user, :users_attribute_c => 'invalid_value') }
it "foreach user" do
[ user1, user2, user3 ].each do |user|
subject { user }
it "should be whatever"
user.should_not be_valid
...
end
end
end
end
However, if I run the above test I get the following error:
Failure/Error: it "should be whatever" do
NoMethodError:
undefined method `it' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_2::Nested_2:0x00000106ccee60>
What is the problem? How can I solve that?
UPDATE after the @Emily answer.
If in the above code I use context "foreach user" do ...
instead of it "foreach user" do ...
I get the following error:
undefined local variable or method `user1' for #<Class:0x00000105310758> (NameError)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题在于一个规范嵌套在另一个规范中。您需要将
它的“foreach user”
替换为context“foreach user”
。编辑添加:经过一番调查,看起来用
let
设置的帮助器仅在it "should ..."
块内可用,而不是在周围的上下文中。我建议尝试寻找不同的结构解决方案。最佳解决方案是什么取决于您实际尝试测试的内容。我猜您想要做的是确保当您删除任何必需的属性时用户无效。在这种情况下,我所做的就是这样的:如果您正在做的事情需要在您正在创建的实例中存在更复杂的差异,则可能没有一种干净的方法来通过迭代来完成它。我认为 DRY 在测试中并不像在代码的其他部分中那么重要。为三种用户类型提供三种不同的上下文并在每种上下文中进行有效性测试并没有什么问题。
The problem is having one spec nested within another. You need to replace
it "foreach user"
withcontext "foreach user"
.Edited to add: After some investigation, it looks like helpers set with
let
are only available inside of theit "should ..."
block, and not in the surrounding context. I'd recommend is trying to find a different structural solution. What the best solution is will depend on what you're actually trying to test. I'm guessing what you're trying to do is make sure the user is invalid when you remove any of the required attributes. In that case, what I've done is something like this:If you're doing something that requires more complex differences in the instance you're creating, there may not be a clean way to do it with iteration. I don't think DRY is quite as essential in testing as it is in other parts of your code. There's nothing wrong with having three different contexts for the three user types, and a validity test in each context.
你正在混合和匹配各种 rspec 的东西。这是你的东西,已修复:
我会这样做:
用最少可能的代码更新“it”语句
You're mixing and matching all sorts of rspec stuff. Here's your stuff, fixed:
I would do it this way:
UPDATE WITH LEAST POSSIBLE CODE
问题是用“let”设置的帮助器不存在于示例上下文之外。
您想要做的事情可以通过以下方式实现:
两种上下文都不同
另一种可能的工作方式(尚未尝试)如下所示:
The problem is that the helpers that are set with "let" do not exist outside of a example context.
What you're trying to do could be achieved as:
Both contexts are different
Another way it might work (haven't tried it) it's like this:
这应该有效。注意上下文是如何编写的,这将使测试的输出更清晰。通过这种方式编写,这意味着(对我来说)您应该分别对每个属性进行测试,但这是您的选择:
This should work. Note how the context is written, it will make the output of tests clearer. From writing it this way it implies (to me) that you should make a test for each attribute separately, but it's your choice: