c# - 我怎样才能模拟这个异步方法?

标签 c# unit-testing asynchronous mocking moq

我有一个大致如下所示的类:

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 接口(interface),以便在调用 BeginGetStaticReferenceData 时它能够调用回调方法。我正在使用最小起订量,但不知道该怎么做。我的单元测试设置代码类似于:

//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);
.
.

最佳答案

方法如下:

[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);
}

这个测试假设一个稍微修改过的 ViewModel,我在其中添加了一些公共(public)成员来测试一些东西:

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);
    }
}

关于c# - 我怎样才能模拟这个异步方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2514926/

相关文章:

c# - 从完整的日期时间模式中仅提取日期模式

c# - 获取 NumericUpDown 的值会移动插入符位置,我可以停止吗?

javascript - getDOM() 在 Angular 2 规范中如何工作

c# - Visual Studio 中的文件驱动单元测试?

swift - 顺序执行函数调用

c# - async/await 创建新线程,输出窗口显示

dataGridView 中的 C# ArgumentOutOfRangeException

ios - OCMock测试类方法

node.js - 在 Meteor 中,Meteor.wrapAsync 是否会阻塞其他调用?

c# - IErrorInfo.GetSource 因 E_FAIL(0x80004005) 而失败