RSpec: як перевірити, чи викликався метод?


112

Коли я пишу тести RSpec, я вважаю, що я пишу багато коду, який виглядає приблизно так, щоб переконатися, що метод був викликаний під час виконання тесту (заради аргументу, скажімо просто, я не можу реально допитати стан об'єкта після виклику, оскільки операція, яку виконує метод, нелегко побачити ефект).

describe "#foo"
  it "should call 'bar' with appropriate arguments" do
    called_bar = false
    subject.stub(:bar).with("an argument I want") { called_bar = true }
    subject.foo
    expect(called_bar).to be_true
  end
end

Що я хочу знати: чи є симпатичніший синтаксис, ніж цей? Чи пропускаю я якусь прикольну приємність RSpec, яка б зменшила вищевказаний код до кількох рядків? should_receiveзвучить так, як слід це робити, але читаючи далі, це здається, що це не зовсім те, що він робить.


3
Перевірте тут: stackoverflow.com/questions/1328277 / ...
kddeisz

@ Петер Альфвін ОП запитував синтаксис should_receive, тому я подумав, що це питання допоможе.
kddeisz

Відповіді:


141
it "should call 'bar' with appropriate arguments" do
  expect(subject).to receive(:bar).with("an argument I want")
  subject.foo
end

1
Вибачте, я не розумію, як цей формат "до .. приймати (: бар)" у цьому прикладі перевіряє значення "call_bar". Чи можете ви мені це пояснити?
ecoding5

2
@ ecoding5 ні. Це не так і не повинно перевіряти called_bar. Це був лише прапор, щоб переконатися, що метод був викликаний, але з expect(...).to receive(...)вами це вже покриваєте. Це більш чітко і семантично
wacko

@wacko oooh, зрозумів, спасибі за очищення, що вийшло. Я не впіймав це вперше.
ecoding5


37

Нижче має працювати

describe "#foo"
  it "should call 'bar' with appropriate arguments" do
     subject.stub(:bar)
     subject.foo
     expect(subject).to have_received(:bar).with("Invalid number of arguments")
  end
end

Документація: https://github.com/rspec/rspec-mocks#expecting-arguments


Дякую - я отримував "NoMethodError", який отримав_рецепцію? - думаю, це може бути пов'язано з вершинами rspec. Я знайшов ще одне рішення, яке працювало для мене (те, що зазначено вище)
Майкі Хогарт

@MikeyHogarth Ця відповідь наводила на думку have_received(підхід після факту "шпигунів"), ні has_received, що не є частиною жодної версії RSpec, яку я знаю.
Пітер Альфвін

2

Щоб повністю відповідати синтаксису RSpec ~> 3.1 та параметром rubocop-rspec'за замовчуванням для правила RSpec/MessageSpies, ось що ви можете зробити з spy:

Очікування від повідомлення ставлять приклад очікування на початку, перш ніж ви почнете використовувати тест на код. Багато розробників вважають за краще використовувати шаблон структурування тестів для структуризації тестів. Шпигуни - це альтернативний тип тестових подвійних, які підтримують цю модель, дозволяючи очікувати, що повідомлення буде отримано після факту, використовуючи have_received.

# arrange.
invitation = spy('invitation')

# act.
invitation.deliver("foo@example.com")

# assert.
expect(invitation).to have_received(:deliver).with("foo@example.com")

Якщо ви не використовуєте rubocop-rspec або використовуєте опцію, що не використовується за замовчуванням. Ви, звичайно, можете використовувати RSpec 3 за замовчуванням з очікуванням.

dbl = double("Some Collaborator")
expect(dbl).to receive(:foo).with("foo@example.com")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.