我正在使用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
为什么?
答案 0 :(得分:2)
原始代码中的问题是,除了nil
之外,它返回first_class == 'Magician'
。如果条件为假,则具有尾随条件的语句返回nil,例如,
> 1 + 1 if true
# => 2
> 1 + 1 if false
# => nil
所有三个测试都是针对每个调用执行的,因此前两个测试的结果会被后续的一个屏蔽掉。
你可以用case语句重写它:
def hp
case first_class
when 'Fighter'
((self[:hp] * 5) * (level + 1))
when 'Ranger'
((self[:hp] * 4) * (level + 1))
when 'Magician'
((self[:hp] * 2) * (level + 1))
end
end
答案 1 :(得分:-1)
我通过将if结构更改为if..elsif来解决此问题。
我猜这显然是返回值,然后另一个如果检查是弄乱的东西。不确定为什么会这样,但是当我这样做时它就起作用了。