Bagaimana cara memverifikasi bahwa metode TIDAK dipanggil dalam Moq?

466

Bagaimana saya memverifikasi bahwa metode TIDAK dipanggil dalam Moq ?

Apakah ada yang seperti AssertWasNotCalled?

UPDATE: Mulai dari Versi 3.0, sintaks baru dapat digunakan:

mock.Verify(foo => foo.Execute("ping"), Times.Never());
alex
sumber

Jawaban:

155

PEMBARUAN : Sejak versi 3, periksa pembaruan untuk pertanyaan di atas atau jawaban Dann di bawah.

Baik, buat tiruan Anda ketat sehingga akan gagal jika Anda memanggil metode yang tidak Anda harapkan

new Mock<IMoq>(MockBehavior.Strict)

Atau, jika Anda ingin tiruan Anda longgar, gunakan .Throws (Exception)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Dan Fish
sumber
9
... atau Callback () untuk mengatur beberapa flag yang dapat ditegaskan.
alex
2
Juga dengan opsi # 2, Anda tidak dapat memiliki VerifyAll dalam metode Teardown umum - itu akan gagal mengatakan bahwa harapan itu tidak terpenuhi; ketika tes idealnya harus lulus.
Gishu
51
Ini sebenarnya bukan "verifikasi tidak dipanggil" karena dapat ditangkap dalam metode dan masih akan berfungsi - memberikan hasil positif palsu!
Dan
4
Harapkan sekarang sudah ditinggalkan
Tomasz Sikora
5
Ini mungkin cara terbaik di tahun 2009, tetapi tentu saja tidak sekarang. maaf
Fabio Milheiro
537

Jalankan verifikasi setelah tes yang memiliki Times.Neverset enum. misalnya

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());
Dan
sumber
4
Apa yang penting di sini adalah bahwa panggilan Verifikasi (tindakan, Jangan) adalah setelah pemanggilan mock. Saya pikir itu sedang menyiapkan verifikasi untuk memanggil VerifyAll () nanti (yang tidak berfungsi)
piers7
Sederhana dan efektif. Terima kasih.
Ian Grainger
45

Dicuri dari: Jawaban John Foster untuk pertanyaan, "Perlu bantuan untuk memahami Moq dengan lebih baik"

Salah satu hal yang mungkin ingin Anda uji adalah metode pembayaran tidak dipanggil ketika seseorang yang berusia di atas 65 masuk ke dalam metode

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {

    var mockPensionService = new Mock<IPensionService>();

    var person = new Person("test", 66);

    var calc = new PensionCalculator(mockPensionService.Object);

    calc.PayPensionContribution(person);

    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}
Chris Marisic
sumber
10

Ini tidak berfungsi dalam versi terbaru dari Moq (karena setidaknya 3.1), itu harus ditentukan dalam Verifymetode sebagaimana disebutkan dalam jawaban.

Sebenarnya, lebih baik untuk menentukan .AtMost(0)setelah pernyataan Pengembalian.

var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);

Meskipun "melempar" juga berfungsi, AtMost(0)IMHO lebih ekspresif.

miha
sumber
-5

Gunakan .AtMostOnce ();

Setelah tes yang sebenarnya, panggil metode itu lagi. Jika melempar pengecualian, itu disebut.

Aaron Digulla
sumber
1
Bukankah sedikit terlalu kabur, untuk menegaskan bahwa pengecualian dilemparkan oleh kerangka mengejek?
alex
Mengapa? Periksa saja jenis pengecualiannya. Jika itu dilempar Moq saya, Anda aman.
Aaron Digulla
8
Menggunakan Verifikasi dengan Times.Never adalah pilihan yang lebih baik ... Saya setuju dengan alex bahwa solusi ini berfungsi, tetapi jelas tidak jelas.
Bip bip