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());

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."));

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());

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());
}

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.


-5

Gunakan .AtMostOnce ();

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


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
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.