2010-01-14 16 views
5

Daha önce oluşturulmuş bir projede birim sınamalarını (xUnit ve Moq kullanarak) kullanmaya başladım. Proje, birleşik konteyner yoluyla bağımlılık enjeksiyonunu yaygın olarak kullanıyor.Adlandırılmış ve erişilen parametrelere erişme

İki hizmet A ve B hizmetim var. Hizmet A, bu durumda test ediliyor. Servis A B'yi çağırır ve dahili bir işleve bir temsilci verir. Bu 'geri arama', ele alması gereken bir mesaj alındığında A'yı bilgilendirmek için kullanılır. (B hizmet B'nin bir örneği) Bu nedenle

bir çağrı:

b.RegisterHandler(Guid id, Action<byte[]> messageHandler); 

bu da şu anda kabul ettiği yolu olarak hizmet A, I, messageHandler dönmesini mümkün gereken test etmek için mesajlar.

Bu, Moq? Kullanılarak yapılabilir mi? yani. RegisterHandler çağrıldığında, messageHandler değeri testime iletilince, hizmet B ile alay edebilir miyim? Ya da bunu yeniden tasarlamak zorunda mıyım? Bu durumda kullanmam gereken tasarım desenleri var mı? Bu tür bir tasarımda herhangi bir iyi kaynak olduğunu bilen var mı?

cevap

9

Sen Geri arama Mock üzerinde yöntemi (isim benzerliği tesadüfi olan) kullanarak geri arama bir örneğini (veya başka bir giriş parametresi) alabilirsiniz ... Visual Studio Birim Test örnek

public class ServiceA 
{ 
    private readonly IServiceB b; 

    public ServiceA(IServiceB b) 
    { 
     if (b == null) 
     { 
      throw new ArgumentNullException("b"); 
     } 

     this.b = b; 
    } 

    public void RegisterCallback() 
    { 
     this.b.RegisterHandler(Guid.NewGuid(), this.Do); 
    } 

    public void Do(byte[] bytes) 
    { 
    } 
} 
: serviceâ bu gibi tanımlanır zaman

[TestMethod] 
public void Test19() 
{ 
    Action<byte[]> callback = null; 

    var bSpy = new Mock<IServiceB>(); 
    bSpy.Setup(b => b.RegisterHandler(It.IsAny<Guid>(), It.IsAny<Action<byte[]>>())) 
     .Callback((Guid g, Action<byte[]> a) => callback = a); 

    var sut = new ServiceA(bSpy.Object); 
    sut.RegisterCallback(); 

    Assert.AreEqual(sut.Do, callback); 
} 

Bu işleri

0

Evet Beklenen ve beklenmeyen işlemlere yanıt vermek için Moq nesnesini ayarlayabilirsiniz. İşte

[TestMethod] 
public void MyTest() 
    { 
     var moqObject = new Mock<ServiceB>(); 

     // Setup the mock object to throw an exception if a certain value is passed to it... 
     moqObject.Setup(b => b.RegisterHandle(unexpectedValue).Throws(new ArgumentException()); 

     // Or, setup the mock object to expect a certain method call... 
     moqObject.Setup(b => b.RegisterHandle(expectedValue)); 

     var serviceA = new ServiceA(moqObject.Object); 

     serviceA.DoSomethingToTest(); 

     // This will throw an exception if an expected operation didn't happen... 
     moqObject.VerifyAll(); 
    } 
İlgili konular