Saya memiliki Antarmuka yang sudah ada sebelumnya ...
public interface ISomeInterface
{
void SomeMethod();
}
dan saya telah memperpanjang pengenalan ini menggunakan mixin ...
public static class SomeInterfaceExtensions
{
public static void AnotherMethod(this ISomeInterface someInterface)
{
// Implementation here
}
}
Saya memiliki kelas yang memanggil ini yang ingin saya uji ...
public class Caller
{
private readonly ISomeInterface someInterface;
public Caller(ISomeInterface someInterface)
{
this.someInterface = someInterface;
}
public void Main()
{
someInterface.AnotherMethod();
}
}
dan tes di mana saya ingin mengejek antarmuka dan memverifikasi panggilan ke metode ekstensi ...
[Test]
public void Main_BasicCall_CallsAnotherMethod()
{
// Arrange
var someInterfaceMock = new Mock<ISomeInterface>();
someInterfaceMock.Setup(x => x.AnotherMethod()).Verifiable();
var caller = new Caller(someInterfaceMock.Object);
// Act
caller.Main();
// Assert
someInterfaceMock.Verify();
}
Namun menjalankan tes ini menghasilkan pengecualian ...
System.ArgumentException: Invalid setup on a non-member method:
x => x.AnotherMethod()
Pertanyaan saya adalah, adakah cara yang bagus untuk mengejek panggilan mixin?
c#
unit-testing
mocking
extension-methods
moq
Russell Giddings
sumber
sumber
Jawaban:
Anda tidak dapat "langsung" menggunakan metode statis (karenanya metode ekstensi) dengan kerangka kerja mengejek. Anda dapat mencoba Moles ( http://research.microsoft.com/en-us/projects/pex/downloads.aspx ), alat gratis dari Microsoft yang menerapkan pendekatan berbeda. Berikut ini deskripsi alatnya:
Anda dapat menggunakan Mol dengan kerangka pengujian apa pun (independen tentang hal itu).
sumber
Saya telah menggunakan Wrapper untuk mengatasi masalah ini. Buat objek pembungkus dan lulus metode mengejek Anda.
Lihat Mengejutkan Metode Statis untuk Pengujian Unit oleh Paul Irwin, ia memiliki contoh yang bagus.
sumber
Saya menemukan bahwa saya harus menemukan bagian dalam metode ekstensi yang saya coba tiru input, dan mengejek apa yang terjadi di dalam ekstensi.
Saya melihat menggunakan ekstensi sebagai menambahkan kode langsung ke metode Anda. Ini berarti saya perlu mengejek apa yang terjadi di dalam ekstensi daripada ekstensi itu sendiri.
sumber
Anda dapat mengejek antarmuka uji yang mewarisi dari yang asli dan memiliki anggota dengan tanda tangan yang sama dengan metode ekstensi.
Anda kemudian dapat mengejek antarmuka uji, menambahkan yang asli ke tiruan dan memanggil metode pengujian dalam pengaturan.
Implementasi mock Anda kemudian dapat memanggil metode apa pun yang Anda inginkan atau cukup memeriksa bahwa metode itu disebut:
Berkat solusi Håvard S di pos ini untuk cara mengimplementasikan tiruan yang mendukung dua antarmuka. Setelah saya menemukannya, mengadaptasinya dengan antarmuka uji dan metode statis adalah cake walk.
sumber
SomeNotAnExtensionMethod
danSomeNotAnExtensionMethod
? Sekarang saya tahu cara membuat tanda tangan metode ekstensi di dalam antarmuka ...iReal
parameter keSomeExtensionMethod
dalam kasusITest
? Jika Anda meneruskannya sebagai parameter pertama, lalu bagaimana cara Anda men-setup?Setup( x=> x.SomeExtensionMethod(x, ...)
ini akan menyebabkan pengecualian runtime.object _mockCache = whatever
... `Setup (x => x.SomeExtensionMethod (...) .. Callback (() => Anda dapat akses _mockCache di sini);)Anda dapat dengan mudah mengejek metode ekstensi dengan JustMock . API sama dengan mengejek metode normal. Pertimbangkan yang berikut ini
Untuk mengatur dan memverifikasi metode ini gunakan yang berikut:
Berikut ini juga tautan ke dokumentasi: Metode Ekstensi Mengejek
sumber
Saya suka menggunakan pembungkus (pola adaptor) ketika saya membungkus objek itu sendiri. Saya tidak yakin saya akan menggunakannya untuk membungkus metode ekstensi, yang bukan bagian dari objek.
Saya menggunakan Properti Injectable Malas internal baik tipe Action, Func, Predicate, atau delegate dan memungkinkan untuk menyuntikkan (menukar) metode selama unit test.
Kemudian Anda memanggil Fungsi bukan metode yang sebenarnya.
Untuk contoh yang lebih lengkap, lihat http://www.rhyous.com/2016/08/11/unit-testing-calls-to-complex-extension-methods/
sumber
Jadi jika Anda menggunakan Moq, dan ingin mengejek hasil dari metode Extension, maka Anda dapat menggunakannya
SetupReturnsDefault<ReturnTypeOfExtensionMethod>(new ConcreteInstanceToReturn())
instance dari kelas mock yang memiliki metode ekstensi yang Anda coba tiru.Ini tidak sempurna, tetapi untuk tujuan pengujian unit ini bekerja dengan baik.
sumber