Saya memiliki tes unit di mana saya harus mengejek metode non-virtual yang mengembalikan tipe bool
public class XmlCupboardAccess
{
public bool IsDataEntityInXmlCupboard(string dataId,
out string nameInCupboard,
out string refTypeInCupboard,
string nameTemplate = null)
{
return IsDataEntityInXmlCupboard(_theDb, dataId, out nameInCupboard, out refTypeInCupboard, nameTemplate);
}
}
Jadi saya punya objek tiruan dari XmlCupboardAccess
kelas dan saya mencoba untuk mengatur tiruan untuk metode ini dalam test case saya seperti yang ditunjukkan di bawah ini
[TestMethod]
Public void Test()
{
private string temp1;
private string temp2;
private Mock<XmlCupboardAccess> _xmlCupboardAccess = new Mock<XmlCupboardAccess>();
_xmlCupboardAccess.Setup(x => x.IsDataEntityInXmlCupboard(It.IsAny<string>(), out temp1, out temp2, It.IsAny<string>())).Returns(false);
//exception is thrown by this line of code
}
Tapi baris ini melempar pengecualian
Invalid setup on a non-virtual (overridable in VB) member:
x => x.IsDataEntityInXmlCupboard(It.IsAny<String>(), .temp1, .temp2,
It.IsAny<String>())
Ada saran bagaimana menyiasati pengecualian ini?
c#
unit-testing
moq
Rahul Lodha
sumber
sumber
XmlCupboardAccess
?virtual
. Moq tidak bisa mengejek tipe beton yang tidak bisa ditimpa.Jawaban:
Moq tidak bisa mengejek metode non-virtual dan kelas disegel. Saat menjalankan tes menggunakan objek tiruan, MOQ sebenarnya membuat jenis proxy di dalam memori yang mewarisi dari "XmlCupboardAccess" Anda dan mengabaikan perilaku yang telah Anda atur dalam metode "SetUp". Dan seperti yang Anda tahu di C #, Anda dapat menimpa sesuatu hanya jika ditandai sebagai virtual yang tidak terjadi pada Java. Java menganggap setiap metode non-statis adalah virtual secara default.
Hal lain yang saya percaya harus Anda pertimbangkan adalah memperkenalkan antarmuka untuk "CupboardAccess" Anda dan mulai mengejek antarmuka. Ini akan membantu Anda memisahkan kode dan memiliki manfaat dalam jangka panjang.
Terakhir, ada kerangka kerja seperti: TypeMock dan JustMock yang bekerja langsung dengan IL dan karenanya dapat mengejek metode non-virtual. Namun keduanya, merupakan produk komersial.
sumber
Sebagai bantuan kepada siapa saja yang memiliki masalah yang sama dengan saya, saya tidak sengaja salah ketik jenis implementasi, bukan antarmuka misalnya
dari pada
sumber
Silakan lihat Mengapa properti yang ingin saya tiru perlu virtual?
Anda mungkin harus menulis antarmuka pembungkus atau menandai properti sebagai virtual / abstrak karena Moq membuat kelas proxy yang digunakannya untuk mencegat panggilan dan mengembalikan nilai kustom yang Anda masukkan ke dalam
.Returns(x)
panggilan.sumber
Alih-alih mengejek kelas beton Anda harus mengejek antarmuka kelas itu. Ekstrak antarmuka dari kelas XmlCupboardAccess
Dan bukannya
mengubah
sumber
Anda juga akan mendapatkan kesalahan ini jika Anda memverifikasi bahwa metode ekstensi suatu antarmuka dipanggil.
Misalnya jika Anda mengejek:
Anda akan mendapatkan pengecualian yang sama karena
.ValidateAndThrow()
merupakan ekstensi padaIValidator<T>
antarmuka.public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null)...
sumber
Kode:
tapi lihat pengecualian.
sumber