Использование rspec для тестирования побочных эффектов
В моей модели 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"
Первая спецификация была достаточно простой для написания, но во втором случае я тестирую побочный эффект и не знаю, как это сделать.
Спасибо
г.
2 ответа
Я согласен с апноэ 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
Первый рефакторинг, отрывок знает слишком много о фразе.
В проходе:
def receives_damage
self.damage += 1
phrases.each do |phrase|
phrase.tap { |p| p.on_blank }.save if phrase.blankable?(damage)
end
save
end
В фразе:
def on_blank
self.blank = true
self.content = content.gsub(/./, " ")
end
def blankable?(damage)
!blank && hit_points <= damage
end
Затем проверьте, получает ли объект фразы правильные методы.