Bayangkan kelas ini
public class Foo {
private Handler _h;
public Foo(Handler h)
{
_h = h;
}
public void Bar(int i)
{
_h.AsyncHandle(CalcOn(i));
}
private SomeResponse CalcOn(int i)
{
...;
}
}
Mo (q) cking Handler dalam ujian Foo, bagaimana saya bisa mengecek apa yang Bar()
telah diteruskan _h.AsyncHandle
?
Jawaban:
Anda dapat menggunakan metode Mock.Callback:
Jika Anda hanya ingin memeriksa sesuatu yang sederhana pada argumen yang diteruskan, Anda juga dapat melakukannya secara langsung:
sumber
Callback<>()
metode Moq generik . Misalnya, jika metode Anda memiliki definisiHandler.AnsyncHandle(string, SomeResponse)
, Anda perlu/* ... */.Callback<string, SomeResponse>(r => result = r);
. Saya belum menemukan ini secara eksplisit di banyak tempat, jadi saya pikir saya akan menambahkannya di sini./* ... */.Callback<string, SomeResponse>((s1, s2) => { str1 = s1; result = s2});
.Callback((string s1, SomeResponse s2) => /* stuff */ )
Capture.In
pembantu bawaan?Jawaban Gamlor bekerja untuk saya, tetapi saya pikir saya akan memperluas komentar John Carpenter karena saya sedang mencari solusi yang melibatkan lebih dari satu parameter. Saya pikir orang lain yang tersandung ke halaman ini mungkin berada dalam situasi yang sama. Saya menemukan info ini di dokumentasi Moq .
Saya akan menggunakan contoh Gamlor, tapi mari kita anggap metode AsyncHandle membutuhkan dua argumen: a
string
danSomeResponse
objek.Pada dasarnya Anda hanya perlu menambahkan yang lain
It.IsAny<>()
dengan tipe yang sesuai, menambahkan tipe lain keCallback
metode, dan mengubah ekspresi lambda yang sesuai.sumber
Metode Callback pasti akan bekerja, tetapi jika Anda melakukan ini pada metode dengan banyak parameter itu bisa sedikit bertele-tele. Berikut adalah sesuatu yang saya gunakan untuk menghapus beberapa boilerplate.
Berikut adalah sumber untuk ArgumentCaptor:
sumber
Jawaban Gamlor bekerja, tetapi cara lain untuk melakukannya (dan yang saya anggap lebih ekspresif dalam tes) adalah ...
Verifikasi sangat kuat, dan layak meluangkan waktu untuk membiasakan diri.
sumber
Alternatifnya adalah dengan menggunakan
Capture.In
fiturmoq
. Ini adalahmoq
fitur OOTB yang memungkinkan pengambilan argumen dalam koleksi.sumber
Callback
IMO. Karena Anda menggunakan Tangkap langsung dalam daftar parameter, itu jauh lebih rentan terhadap masalah ketika refactoring daftar parameter metode, dan karenanya membuat tes lebih rapuh. Dengan Callback, Anda harus menjaga agar parameter yang lulus dalam Pengaturan tetap sinkron dengan parameter jenis yang digunakan untuk Callback, dan itu pasti telah menyebabkan masalah pada saya di masa lalu.Anda bisa menggunakan
It.Is<TValue>()
pencocokan.sumber
Ini juga berfungsi:
sumber
Banyak jawaban bagus di sini! Pergilah dengan set fitur yang ada di luar kotak Moq sampai Anda perlu membuat pernyataan tentang beberapa parameter kelas yang diteruskan ke dependensi Anda. Jika Anda berakhir dalam situasi itu, fitur Verifikasi Moq dengan It. Pencocokan tidak melakukan pekerjaan yang baik untuk mengisolasi kegagalan tes, dan cara Pengembalian / Panggilan Balik untuk menangkap argumen menambahkan baris kode yang tidak perlu ke pengujian Anda (dan tes panjang adalah jalan keluar bagi saya).
Berikut adalah intinya: https://gist.github.com/Jacob-McKay/8b8d41ebb9565f5fca23654fd944ac6b dengan ekstensi Moq (4,12) yang saya tulis yang memberikan cara yang lebih deklaratif untuk membuat pernyataan tentang argumen yang dilontarkan ke ejek, tanpa kekurangan yang disebutkan di atas. Berikut ini bagian Verify sekarang:
Saya akan terpacu jika Moq menyediakan fitur yang melakukan hal yang sama sementara menjadi deklaratif dan menyediakan isolasi kegagalan ini. Semoga saja!
sumber