2011-03-05 86 views
-1

我使用Rspec和工厂女孩来设置我的测试。我有一个用户工厂,然后我用rspec进行测试。带工厂的Rspec和来自模型的虚拟属性不起作用?

在一个名为GameEngine ::公式,我有一个虚拟属性模块(实际上马力已经是我的模型,它在这里覆盖):

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 

当我删除该虚拟ATTRIB,测试工作正常。但是,如果我离开这里,我得到的是:

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

什么是您的工厂是什么样子? – raidfive 2011-03-06 03:59:02

+0

我加了工厂。我实际上通过改变ifs结构thanx来解决这个问题。 – Spyros 2011-03-06 04:10:12

回答

2

原始代码中的问题是,除first_class == 'Magician'以外,它返回nil。如果条件为假,则带尾随条件的语句返回零。

> 1 + 1 if true 
# => 2 

> 1 + 1 if false 
# => nil 

所有三个测试对每个调用进行,所以第2的结果由随后的一个(多个)屏蔽。

你可以用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 
+0

伟大的解释thanx! – Spyros 2011-03-06 06:43:47

-1

我通过将if结构更改为if..elsif来解决此问题。

我想显式返回的值,然后有另一个检查是搞砸的东西。不确定为什么会出现这种情况,但是当我这样做时,它就起作用了。