2010-03-25 42 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包含有关如何使用犀牛制品测试异步方法很好的解释 - 我敢肯定,它可以很容易地适合于使用起订量来代替。