带有工厂和模型虚拟属性的 Rspec 不起作用?
我正在使用 Rspec 和工厂女孩来设置我的测试。我有一个用户工厂,然后我正在使用 rspec 进行测试。
在名为 GameEngine::Formulas 的模块中,我有一个虚拟属性(实际上 hp 已经是模型,它在这里被覆盖):
def hp
((self[:hp] * 5) * (self.level + 1)) if self.first_class == 'Fighter'
((self[:hp] * 4) * (self.level + 1)) if self.first_class == 'Ranger'
((self[:hp] * 2) * (self.level + 1)) if self.first_class == 'Magician'
end
当我删除这个虚拟属性时,测试工作正常。但如果我把它留在这里,我就会明白:
Failure/Error: let(:user) { Factory(:user) }
ActiveRecord::RecordInvalid:
Validation failed: Hp can't be blank
工厂:
Factory.define :user do |f|
f.sequence(:username) { |n| "test#{n}" }
f.password "1234567890"
f.sequence(:email) { |n| "test#{n}@test.com" }
f.first_class 'Ranger'
f.hp 10000
f.strength 100
f.magic 100
f.dexterity 100
f.accuracy 10
f.armor 20
f.level 1
end
为什么会这样?
i'm using Rspec and factory girl to set my tests. I have a user factory and then i'm testing with rspec.
In a module named GameEngine::Formulas, i have a virtual attribute(actually hp is already i the model, it's overridden here) :
def hp
((self[:hp] * 5) * (self.level + 1)) if self.first_class == 'Fighter'
((self[:hp] * 4) * (self.level + 1)) if self.first_class == 'Ranger'
((self[:hp] * 2) * (self.level + 1)) if self.first_class == 'Magician'
end
When i remove this virtual attrib, the test works fine. But if i leave it here, i get that :
Failure/Error: let(:user) { Factory(:user) }
ActiveRecord::RecordInvalid:
Validation failed: Hp can't be blank
FACTORY :
Factory.define :user do |f|
f.sequence(:username) { |n| "test#{n}" }
f.password "1234567890"
f.sequence(:email) { |n| "test#{n}@test.com" }
f.first_class 'Ranger'
f.hp 10000
f.strength 100
f.magic 100
f.dexterity 100
f.accuracy 10
f.armor 20
f.level 1
end
Why is that ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
原始代码中的问题是,除非
first_class == 'Magician'
,否则它会返回nil
。如果条件为 false,则带有尾随条件的语句将返回 nil,例如,每次调用都会执行所有三个测试,因此前两个测试的结果会被后续测试的结果所掩盖。
您可以用 case 语句重写它:
The problem in the original code is that it returns
nil
except whenfirst_class == 'Magician'
. A statement with a trailing conditional returns nil if the condition is false, e.g.All three tests are performed for each invocation, so the results of the first two are masked by the subsequent one(s).
You could rewrite it with a case statement:
我通过将 if 结构更改为 if..elsif 解决了这个问题。
我猜想显式返回值然后再进行另一个 if 检查会弄乱事情。不确定为什么会出现这种情况,但当我这样做时它起作用了。
I resolved this by changing the if structure to if..elsif.
I guess that explicitly returning the value and then having another if check was messing the things. Not sure exactly why this is the case, but it worked when i did that.