Verifikasi panggilan metode menggunakan Moq

151

Saya cukup baru untuk pengujian unit di C # dan belajar menggunakan Moq. Di bawah ini adalah kelas yang saya coba uji.

class MyClass
{
    SomeClass someClass;
    public MyClass(SomeClass someClass)
    {
        this.someClass = someClass;     
    }

    public void MyMethod(string method)
    {
        method = "test"
        someClass.DoSomething(method);
    }   
}

class Someclass
{
    public DoSomething(string method)
    {
        // do something...
    }
}

Di bawah ini adalah TestClass saya:

class MyClassTest
{
    [TestMethod()]
    public void MyMethodTest()
    {
        string action="test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();
        mockSomeClass.SetUp(a => a.DoSomething(action));
        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);
        mockSomeClass.Verify(v => v.DoSomething(It.IsAny<string>()));
    }
}

Saya mendapatkan pengecualian berikut:

Expected invocation on the mock at least once, but was never performed
No setups configured.
No invocations performed..

Saya hanya ingin memverifikasi apakah metode "MyMethod" dipanggil atau tidak. Apakah saya melewatkan sesuatu?

pengguna591410
sumber
1
Itu tidak akan dikompilasi jika SomeClasstidak memiliki definisi MyMethod(string), yang sepertinya tidak.
Platinum Azure
maaf..Saya mengedit pertanyaan saya ..
pengguna591410
1
Anda berada di jalur yang benar, tetapi ada bug di kode yang diposting. Itu tidak akan mengkompilasi - casing pada Someclass, batal pengembalian DoSomething. Setelah itu Anda membutuhkan akses publik, lalu jadikan DoSomething virtual. Singkatnya, Anda mungkin memiliki bug dalam kode produksi Anda juga.
TrueWill
Terimakasih atas tanggapan Anda. Saya salah menyetel argumen saat menyiapkan metode tiruan ..
user591410
"Tidak ada pengaturan yang dikonfigurasi." Bisa menyesatkan. Anda tidak perlu menyiapkan perilaku untuk metode yang akan dipanggil. Dan juga ingat untuk menjalankan metode "Verifikasi" SETELAH metode yang Anda uji harus dipanggil (jadi tidak masalah dalam kasus Anda).
Sielu

Jawaban:

218

Anda memeriksa metode yang salah. Moq mengharuskan Anda menata (dan kemudian secara opsional memverifikasi) metode di kelas ketergantungan.

Anda harus melakukan sesuatu yang lebih seperti ini:

class MyClassTest
{
    [TestMethod]
    public void MyMethodTest()
    {
        string action = "test";
        Mock<SomeClass> mockSomeClass = new Mock<SomeClass>();

        mockSomeClass.Setup(mock => mock.DoSomething());

        MyClass myClass = new MyClass(mockSomeClass.Object);
        myClass.MyMethod(action);

        // Explicitly verify each expectation...
        mockSomeClass.Verify(mock => mock.DoSomething(), Times.Once());

        // ...or verify everything.
        // mockSomeClass.VerifyAll();
    }
}

Dengan kata lain, Anda memverifikasi panggilan itu MyClass#MyMethod, kelas Anda pasti akan menelepon SomeClass#DoSomethingsekali dalam proses itu. Perhatikan bahwa Anda tidak membutuhkan Timesargumen; Saya baru saja mendemonstrasikan nilainya.

Platinum Azure
sumber
Maaf, saya mengedit pertanyaan saya dengan metode yang benar. Seperti yang Anda sebutkan, saya mencoba SetUp terlebih dahulu dan kemudian melakukan Verifikasi. Itu masih memberi saya pengecualian yang sama.
pengguna591410
23
Bukankah itu mubazir untuk menyiapkan ekspektasi, lalu secara eksplisit memverifikasi ekspektasi yang sama? Tidakkah mockSomeClass.VerifyAll();mencapai hasil yang sama dan menjadi lebih KERING?
Tim Long
14
Ya itu akan tetapi beberapa orang lebih suka bersikap eksplisit.
Platinum Azure
3
Terima kasih telah setidaknya menyebutkan VerifyAll (); sementara jelas setelah Anda memikirkannya. Saya mungkin memilih pendekatan eksplisit, tetapi jauh lebih bersih saat menggunakan semuanya. Bersyukur keduanya terdaftar.
JGood
1
Satu kelemahan terkait dari Mockdibandingkan dengan NSubstituteadalah bahwa jika Anda mencoba untuk memverifikasi juga parameter dan verifikasi gagal, itu hanya menunjukkan pemanggilan apa yang dilakukan, tetapi tidak menunjukkan apa yang diharapkan jika Anda menggunakan variabel dalam ekspresi verifikasi - itu hanya akan menunjukkan variabel nama, bukan nilainya, jadi Anda harus men-debug untuk memeriksa nilai sebenarnya yang dimiliki variabel itu. NSubstitute hanya akan menampilkan nilai keduanya dan bahkan di tempat yang berbeda.
Grengas