RSpec: bagaimana cara menguji apakah suatu metode dipanggil?


112

Saat menulis tes RSpec, saya mendapati diri saya menulis banyak kode yang terlihat seperti ini untuk memastikan bahwa sebuah metode dipanggil selama pelaksanaan tes (demi argumen, anggap saja saya tidak bisa benar-benar menginterogasi status objek setelah panggilan karena operasi yang dilakukan metode tidak mudah untuk melihat efeknya).

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

Yang ingin saya ketahui adalah: Apakah ada sintaks yang lebih bagus yang tersedia dari ini? Apakah saya kehilangan beberapa RSpec funky yang akan mengurangi kode di atas menjadi beberapa baris? should_receiveterdengar seperti itu harus melakukan ini tetapi membaca lebih lanjut kedengarannya seperti itu tidak persis seperti itu.



@ Peter Alfvin OP meminta sintaks should_receive, jadi saya pikir pertanyaan itu akan membantu.
kddeisz

Jawaban:


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

1
Maaf, saya tidak mengerti bagaimana format "to .. accept (: bar)" memeriksa nilai "calling_bar" dalam contoh ini. Bisakah Anda menjelaskan itu kepada saya?
ecoding5

2
@ ecoding5 no. Itu tidak dan tidak harus diperiksa called_bar. Itu hanya sebuah tanda untuk memastikan bahwa metode tersebut dipanggil, tetapi expect(...).to receive(...)Anda sudah menutupinya. Ini lebih jelas dan semantik
aneh

@wacko oooh, mengerti, terima kasih sudah menyelesaikannya. Saya tidak menangkapnya pertama kali.
ecoding5


37

Di bawah ini harus bekerja

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

Dokumentasi: https://github.com/rspec/rspec-mocks#expecting-arguments


Terima kasih - Saya menerima "NoMethodError" has_received? - pikir ini mungkin ada hubungannya dengan versoins rspec sekalipun. Saya menemukan solusi lain yang berhasil untuk saya (yang ditandai benar di atas)
Mikey Hogarth

@MikeyHogarth Jawaban ini menyarankan have_received(setelah fakta pendekatan "mata-mata"), bukan has_received, yang bukan bagian dari versi RSpec mana pun yang saya tahu.
Peter Alfvin

2

Untuk sepenuhnya mematuhi sintaks RSpec ~> 3.1 dan rubocop-rspecopsi default untuk aturan RSpec/MessageSpies, inilah yang dapat Anda lakukan dengan spy:

Ekspektasi pesan meletakkan ekspektasi contoh di awal, sebelum Anda menjalankan code-under-test. Banyak pengembang lebih suka menggunakan pola tata-tindakan-pernyataan (atau diberikan-saat-kemudian) untuk menyusun pengujian. Mata-mata adalah jenis tes ganda alternatif yang mendukung pola ini dengan memungkinkan Anda mengharapkan bahwa pesan telah diterima setelah fakta, menggunakan has_received.

# arrange.
invitation = spy('invitation')

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

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

Jika Anda tidak menggunakan rubocop-rspec atau menggunakan opsi non-default. Anda tentu saja dapat menggunakan RSpec 3 default dengan harapan.

dbl = double("Some Collaborator")
expect(dbl).to receive(:foo).with("foo@example.com")
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.