在我的模型Passages
中,我有一个方法receives_damage
:
def receives_damage
self.damage += 1
self.phrases.each do |phrase|
if !phrase.blank && phrase.hit_points <= self.damage
phrase.blank = true
phrase.content = phrase.content.gsub(/./, " ")
phrase.save
end
end
self.save
end
在receives_damage
的模型规格中,我有:
it "it increases the damage by 1"
it "it blanks any phrases with few enough hitpoints"
第一个规格很容易写,但在第二个案例中,我正在测试副作用,我不知道该怎么做。
由于
Ž。
答案 0 :(得分:2)
我同意apneadiving您的对象Passage
对Phrase
了解太多。但是,由于您具体询问了给定示例,因此可以通过设置对象状态来执行此操作:
it "blanks any phrases with few enough hitpoints"
low_hp = 3.times.map{ create :phrase, hp: 1 } # Or however you create them
high_hp = 2.times.map{ create :phrase, hp: 1_000_000 }
passage.phrases = low_hp + high_hp # Or however you can set this state
passage.receives_damage
expect(low_hp.map(&:content)).to match_array [".", ".", "."]
end
我可能会建议为最后编写一个更好的自定义匹配器。这样你就可以正确地说出更好的东西,例如:
expect{passage.receive_damage}.to blank_phrases low_hp
答案 1 :(得分:1)
第一个重构,段落对词组知之甚多。
In Passage:
def receives_damage
self.damage += 1
phrases.each do |phrase|
phrase.tap { |p| p.on_blank }.save if phrase.blankable?(damage)
end
save
end
In Phrase:
def on_blank
self.blank = true
self.content = content.gsub(/./, " ")
end
def blankable?(damage)
!blank && hit_points <= damage
end
然后检查短语对象是否收到正确的方法。