2010-03-25 115 views
9

我有一個類,大致是這樣的:如何模擬這種異步方法?

public class ViewModel 
{ 
    public ViewModel(IWebService service) 
    { 
    this.WebService = service; 
    } 

    private IWebService WebService{get;set;} 
    private IEnumerable<SomeData> MyData{get;set;} 

    private void GetReferenceData() 
    { 
    this.WebService.BeginGetStaticReferenceData(GetReferenceDataOnComplete, null); 
    } 

    private void GetReferenceDataOnComplete(IAsyncResult result) 
    { 
    this.MyData = this.WebService.EndGetStaticReferenceData(result); 
    } 
    . 
    . 
    . 
} 

我想模仿我IWebService接口,這樣,當BeginGetStaticReferenceData被稱爲它能夠調用回調方法。我正在使用Moq,我無法解決如何做到這一點。我的單元測試設置的代碼看起來是這樣的:

//Arrange 
var service = new Mock<IWebService>(); 
service.Setup(x => x.BeginGetStaticReferenceData(/*.......don't know.....*/)); 
service.Setup(x => x.EndGetStaticReferenceData(It.IsAny<IAsyncResult>())).Returns(new List<SomeData>{new SomeData{Name="blah"}}); 
var viewModel = new ViewModel(service.Object); 
. 
. 

回答

19

方法如下:

[TestMethod] 
public void Test10() 
{ 
    var expectedData = new[]{new SomeData(), new SomeData()}; 

    AsyncCallback callback = null; 
    IAsyncResult ar = new Mock<IAsyncResult>().Object; 

    var webServiceStub = new Mock<IWebService>(); 
    webServiceStub 
     .Setup(ws => ws.BeginGetStaticReferenceData(It.IsAny<AsyncCallback>(), null)) 
     .Callback((AsyncCallback cb, object state) => callback = cb) 
     .Returns(ar); 
    webServiceStub 
     .Setup(ws => ws.EndGetStaticReferenceData(It.IsAny<IAsyncResult>())) 
     .Returns(expectedData); 

    var sut = new ViewModel(webServiceStub.Object); 
    sut.DoIt(); 

    callback(ar); 

    Assert.AreEqual(expectedData, sut.MyData); 
} 

該測試假定一個稍微修改視圖模型,我增加了一些公衆的成員有一些針對其測試:

public class ViewModel 
{ 
    public ViewModel(IWebService service) 
    { 
     this.WebService = service; 
    } 

    public IEnumerable<SomeData> MyData { get; set; } 

    public void DoIt() 
    { 
     this.GetReferenceData(); 
    } 

    private IWebService WebService { get; set; } 

    private void GetReferenceData() 
    { 
     this.WebService.BeginGetStaticReferenceData(GetReferenceDataOnComplete, null); 
    } 

    private void GetReferenceDataOnComplete(IAsyncResult result) 
    { 
     this.MyData = this.WebService.EndGetStaticReferenceData(result); 
    } 
} 
+0

真棒,這真是棒極了。謝謝! – Charlie

+0

我試着調整這個UdpClient,並且它只有當我把你的回調從'=> callback = cb'改成'=> cb(ar)'時才起作用。不知道我是否已經入侵過怪物或什麼... – Benjol

+0

什麼是上面的模擬類?是你的課程還是我需要添加一些參考來使用它? –

0

article包含有關如何使用犀牛製品測試異步方法很好的解釋 - 我敢肯定,它可以很容易地適合於使用起訂量來代替。