Bir yöntemin çağrılıp çağrılmadığını belirlemek için Adedi kullanma


159

Daha yüksek düzeyli bir yöntem çağırırsanız, bir yöntem çağrısının gerçekleşeceğini test edebileceğimi anlıyorum, yani:

public abstract class SomeClass()
{    
    public void SomeMehod()
    {
        SomeOtherMethod();
    }

    internal abstract void SomeOtherMethod();
}

Bunu denemek SomeMethod()istersem o SomeOtherMethod()zaman bunun çağrılmasını beklerim.

Bu tür bir testin alaycı bir çerçeve içinde mevcut olduğunu düşünmekte haklı mıyım?

Yanıtlar:


186

Alay ettiğiniz bir şeydeki bir yöntemin Verify kullanılarak çağrılıp çağrılmadığını görebilirsiniz, örneğin:

static void Main(string[] args)
{
        Mock<ITest> mock = new Mock<ITest>();

        ClassBeingTested testedClass = new ClassBeingTested();
        testedClass.WorkMethod(mock.Object);

        mock.Verify(m => m.MethodToCheckIfCalled());
}

class ClassBeingTested
{
    public void WorkMethod(ITest test)
    {
        //test.MethodToCheckIfCalled();
    }
}

public interface ITest
{
    void MethodToCheckIfCalled();
}

Satır yorumda bırakılırsa, Doğrulama'yı çağırdığınızda bir MockException oluşturur. Uncommented ise geçecektir.


7
Bu doğru cevap. Ancak bir şey anlamalısınız. Soyut veya sanal olmayan bir yöntemi / özelliği alamazsınız (açıkçası, tüm arabirim yöntemleri ve özellikleri alay edilebilir).

25
-1: .Expect (...). Doğrulanabilir () bu kodda yedeklidir. AAA kullanarak doğrulamak doğru. Doğrulanabilir .Verify () i, .e ile kullanım içindir. arg sürümü yok. Bkz. Stackoverflow.com/questions/980554/…
Ruben Bartelink

@ Ben evet olabilir
reggaeguitar

6

Hayır, alay testi, biri enjeksiyon olan belirli test edilebilir tasarım desenleri kullandığınızı varsayar. Sizin durumunuzda test ediyor olacaksınız SomeClass.SomeMethod ve SomeOtherMethodarayüzlenmesi gereken başka bir tüzel kişide uygulanması gerekir.

Sizin Someclassyapıcı gibi görünecektir New(ISomeOtherClass). Sonra alay ISomeOtherClassve onun üzerinde beklenti ayarlamak ve beklenti SomeOtherMethoddoğrulamak.


0

@ Paul'un cevabının tavsiye edilen yol olduğunu kabul etsem de, sadece kendim tarafından sağlanan alternatif bir yol eklemek istiyorum moq.

Yana SomeClassolduğunu abstractgerçekten mockable, ama public void SomeMehod()değil. Mesele, bu yöntemi alay etmenin ve bir şekilde bu yöntemi çağırmanın ve ardından CallBaseçağrıyı SomeOtherMethod(). Bir saldırı gibi gelebilir ama özünde basittir. Önerilen yeniden düzenleme işleminin mümkün olmadığı durumlarda kullanılabilir.

// This class is used only for test and purpose is make SomeMethod mockable
public abstract class DummyClass : SomeClass
{
    public virtual void DummyMethod() => base.SomeMethod();
}

Ardından DummyMethod(), CallBasebayrağı ayarlayarak çağrıyı yaymak için ayarlayabilirsiniz .

//Arrange
var mock = new Mock<DummyClass>();
mock.Setup(m => m.DummyMethod()).CallBase();

//Act
mock.Object.SomeMethod();

//Assert
mock.Verify(m => m.SomeOtherMethod(), Times.Once);

Daha karmaşık ve kaynatma plakası gerektiren bir DummyClass gerektirdiği için indirildi
reggaeguitar

çünkü bazen refactor olamaz ve uygulamayı olduğu gibi test etmek gerekir
wickdninja
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.