所以我有一个复杂的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个是一团糟。
有什么想法吗?
答案 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