仅为循环中的某些对象变量赋值

时间:2014-02-21 20:39:11

标签: ruby-on-rails ruby rspec

所以我有一个复杂的RPG角色模型,我正在做一个侧面项目。对于这个角色扮演游戏,每个角色都有6个基本的“能力分数”(力量,灵巧,体质,智慧,智慧,魅力)。我特别关注将它们设置为0的测试,这应该是无效的(角色死亡等)。这是我在rspec中的内容:

describe "when ability scores are 0" do
  ability_scores = %w(strength dexterity constitution
                      intelligence wisdom charisma)
  ability_scores.each do |ability_score|
    @character.ability_score = 0
    expect(@character).to be_invalid
  end
end

我在文件的开头有一个工厂,创建一个完全有效的字符并设置subject { @character }

我会认为它会看到ability_score,并且在评估角色对象之前考虑插入它的值,但似乎并非如此。

@character.send(:"#{ability_score}=", 0)切换@character.ability_score = 0会产生NoMethodError: undefined method 'strength=' for nil:NilClass

但是,单独的describe块可以正常工作:

describe "when strength is 0" do
  before { @character.strength = 0 }
  it { should_not be_valid }
end

但其中有6个是一团糟。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

这一行存在问题

character.ability_score = 0

这一行在:ability_score=对象上发送一个名为character的方法,但我认为你想要的是设置你要迭代的字符串数组所引用的变量。

幸运的是,您可以使用send在对象上调用任意方法。您可以将字符串转换为引用setter方法的符号,然后将其作为消息发送到character

character.send(:"#{ability_score}=", 0)

(注意:您实际上不需要发送符号;如果您愿意,可以将其保留为字符串)。 实际上,这与调用character.strength = 0等完全相同。

修改

更改describe块的内容以定义测试:

describe "when ability scores are 0" do
  %w(strength dexterity constitution intelligence wisdom charisma).each do |ability_score|
    it "is invalid when #{ability_score} is 0" do
      @character.send("#{ability_score}=", 0)
      expect(@character).to be_invalid
    end
  end
end