2010-07-17 16 views
107

bu sınıfı düşününMoq: Bir alay hizmetin bir yönteme geçirilen bir parametre almak için nasıl

public class Foo { 

    private Handler _h; 

    public Foo(Handler h) 
    { 
     _h = h; 
    } 

    public void Bar(int i) 
    { 
     _h.AsyncHandle(CalcOn(i)); 
    } 

    private SomeResponse CalcOn(int i) 
    { 
     ...; 
    } 
} 

Mo ne denetlemek mümkün olacaktır nasıl Foo bir testte (q) cking Handler, Bar()_h.AsyncHandle'a geçti?

+0

siz "AsyncHandle" (ekstra "n") kastettiniz? Ve Handler için kodu gönderebilir veya standart bir tipse tam nitelikli tip adını belirtebilir misiniz? – TrueWill

+0

Düşüncelerinizi göstermek için iskelet testinizi gösterebilir misiniz? Ben sizin tarafınızdan açıkça anlaşılırken, bizim tarafımızdan açık bir şekilde, uzun spekülatif bir cevap vermeden, soruyu cevaplamak için zamanı almayan birine benziyor. –

+1

Ne Foo ne de Bar() ne de bunun gibi bir şey yoktur. Başvuru koşullarından rahatsızlık duymadan durumumu göstermek için sadece bir demo kodu. Ve sadece cevabı aldım, elde etmeyi umuyordum. – Jan

cevap

178

Sen Mock.Callback-yöntemi kullanabilirsiniz: Yalnızca argüman geçirilen üzerine basit bir şey kontrol etmek istiyorsanız

var mock = new Mock<Handler>(); 
SomeResponse result = null; 
mock.Setup(h => h.AnsyncHandle(It.IsAny<SomeResponse>())) 
    .Callback<SomeResponse>(r => result = r); 

// do your test 
new Foo(mock.Object).Bar(22); 
Assert.NotNull(result); 

, ayrıca doğrudan yapabilirsiniz:

mock.Setup(h => h.AnsyncHandle(It.Is<SomeResponse>(response => response != null))); 
+1

mükemmel, teşekkürler! – Jan

+14

Bir yan not, işlevinize birden fazla argümanınız varsa, jenerik 'Geri arama <>()' Moq yöntemindeki tüm türleri belirtmeniz gerekir. Örneğin, eğer metod Handler.AnsyncHandle (string, SomeResponse) 'i tanımladıysanız,'/* ... * /. Geri arama (r => result = r); Bunu pek çok yerde açıkça belirtmedim, bu yüzden buraya ekleyeceğimi düşündüm. –

17

Gamlor en cevap çalışır, ancak bunu yapmanın başka bir yolu (ve testte daha açıklayıcı olduğunu düşündüğüm bir tane) ... ( )Doğrulama çok güçlü ve alışmak için zaman ayırmaya değer.

+9

Bu yöntem, bir yöntemin bilinen bir parametreyle çağrılıp çağrılmadığını kontrol etmek istiyorsanız iyi olur. Parametrenin test yazma noktasında henüz yaratılmamış olması durumunda (örneğin, söz konusu ünite dahili olarak parametreyi yaratır), Geri Çağırma, bunu yakalamanıza ve sorgulamanıza olanak verirken, yaklaşımınız bunu yapmaz. – Michael

+0

Geçirilen değeri saklamam gerekir çünkü geçirilen tüm nesne kümelerinin doğrulanması gerekiyor. – MrFox

1

Sen It.Is<TValue>() eşleyici kullanabilirsiniz.

var mock = new Mock<Handler>(); new Foo(mock.Object).Bar(22); mock.Verify(h => h.AsyncHandle(It.Is<SomeResponse>(r => r != null)));

+0

Typo - 'AnsyncHandle', 'AsyncHandle' olmalı –

2

Gamlor cevabı benim için çalıştı, ama ben birden fazla parametreyi içeren bir çözüm arıyordu çünkü John Carpenter'ın yorumum genişletmek düşündüm. Bu sayfaya karışan diğer insanların da benzer bir durumda olabileceğini düşündüm. Bu bilgiyi Moq documentation'da buldum.

Gamlor'un örneğini kullanacağız, ancak AsyncHandle yönteminin iki argüman aldığını varsayalım: string ve SomeResponse nesnesi.

var mock = new Mock<Handler>(); 
string stringResult = string.Empty; 
SomeResponse someResponse = null; 
mock.Setup(h => h.AsyncHandle(It.IsAny<string>(), It.IsAny<SomeResponse>())) 
    .Callback<string, SomeResponse>((s, r) => 
    { 
     stringResult = s; 
     someResponse = r; 
    }); 

// do your test 
new Foo(mock.Object).Bar(22); 
Assert.AreEqual("expected string", stringResult); 
Assert.IsNotNull(someResponse); 

Temelde sadece, Uygun türde başka It.IsAny<>() eklemek Callback yöntemine başka tür ekleyin ve uygun şekilde Lambda ifade değiştirmeniz gerekir.

İlgili konular