Adedi kullanarak yöntem çağrısını doğrulama


142

C # birim testi ve Moq kullanmayı öğrenmek için oldukça yeniyim. Aşağıda test etmeye çalıştığım sınıf var.

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

Aşağıda benim TestClass'ım:

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

Aşağıdaki istisnayı alıyorum:

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

Sadece "MyMethod" yönteminin çağrılıp çağrılmadığını doğrulamak istiyorum. Bir şey mi kaçırıyorum?


1
SomeClassBir tanımı yoksa derlenmeyecektir MyMethod(string), öyle görünmemektedir.
Platinum Azure

üzgünüm .. Sorumu düzenledim ..
user591410

1
Doğru yoldasınız, ancak yayınlanan kodda hatalar var. Derlenmeyecek - Someclass'a kasa, DoSomething'e geri dönüşü geçersiz kılar. Bundan sonra herkese açık erişime ihtiyacınız var, ardından DoSomething'i sanal hale getirin. Kısacası, muhtemelen üretim kodunuzda bir hata var.
TrueWill

Yanıtınız için teşekkürler. Sahte yöntemi ayarlarken argümanları yanlış ayarlıyordum ..
user591410

"Hiçbir kurulum yapılandırılmadı." Yanıltıcı olabilir. Çağrılacak yöntemler için bir davranış ayarlamanıza gerek yoktur. Ayrıca, test ettiğiniz yöntemin çağrılmasından SONRA "Doğrula" yöntemini uygulamayı unutmayın (bu durumda sizin durumunuzda bir sorun yoktur).
Sielu

Yanıtlar:


209

Yanlış yöntemi kontrol ediyorsunuz. Moq bağımlılık sınıfında yöntemi Kur (ve sonra isteğe bağlı olarak Doğrula) gerektirir.

Bunun gibi bir şey daha yapmalısınız:

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

Başka bir deyişle, MyClass#MyMethodsınıfınızın SomeClass#DoSomethingbu süreçte kesinlikle bir kez arayacağını doğrularsınız . TimesTartışmaya ihtiyacınız olmadığını unutmayın ; Sadece değerini gösteriyordum.


Üzgünüm, sorumu doğru yöntemle düzenledim. Bahsettiğiniz gibi, önce SetUp'ı denedim ve ardından Doğrulama işlemini gerçekleştirdim. Yine de aynı istisnayı veriyor.
user591410

22
Bir beklenti ayarlamak ve aynı beklentiyi açıkça doğrulamak gereksiz mi? Olmaz mockSomeClass.VerifyAll();aynı sonucu elde etmek ve daha KURU olabilir mi?
Tim Long

14
Evet, ama bazı insanlar açık olmayı tercih eder.
Platinum Azure

3
En azından VerifyAll () 'dan bahsettiğiniz için teşekkür ederiz; bir kez düşündüğünüzde belliydi. Ben açık bir yaklaşım için gitmiş olabilir, ama hepsini kullanırken çok daha temiz. Minnettar her ikisi de listelenir.
JGood

1
Biri ilgili dezavantaj Mockkarşılaştırıldığında NSubstituteayrıca parametreleri doğrulamak için çalışıyoruz ve doğrulama invocations yapıldı neyi, sadece gösteri başarısız, ancak doğrulama ifadede değişkenler kullanıldığında tam olarak ne bekleniyordu gelmezse olmasıdır - bu sadece değişkeni gösterecektir adı değil değerini alır, bu nedenle bu değişkenin tam olarak hangi değere sahip olduğunu kontrol etmek için hata ayıklamanız gerekir. NSubstitute, her ikisinin de değerlerini ve hatta farklı olduğu yerleri gösterecektir.
Grengas
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.