【问题标题】:Assigning value to only certain object variables in a loop仅在循环中为某些对象变量赋值
【发布时间】:2014-02-25 04:19:24
【问题描述】:

所以我有一个复杂的 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 个这样的东西是一团糟。

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails ruby rspec


    【解决方案1】:

    这行有问题

    character.ability_score = 0
    

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

    幸运的是,您可以使用 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
    

    【讨论】:

    • 导致NoMethodError: undefined method 'strength=' for nil:NilClass,还将对字符的引用更改为实例变量。分配在单独的描述块中工作。我将两者都添加到我原来的问题中。
    • 你在哪里初始化@character
    • 您的期望似乎只是在 describe 块的上下文中发生,而不是在实际测试中(it { ... }specify { .. })。在该范围内无法访问实例变量(请参阅编辑后的答案)。
    • 这是有道理的。鉴于it/specify 问题,我改写了代码以在测试期间分配。这解决了问题。 @character 正在使用 let 在根 describe 块中初始化,并由工厂构建。谢谢@zach-kemp!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    相关资源
    最近更新 更多