【问题标题】:How to setup a BeginXXX EndXXX method call with moq?如何使用 moq 设置 BeginXXX EndXXX 方法调用?
【发布时间】:2012-07-01 16:24:55
【问题描述】:

假设我有一些 APM (BeginXxx, EndXxx) 模式异步方法(作为我正在调用的某些 WCF 服务代理的一部分):

public interface ISomeService
{
    IAsyncResult BeginSomeMethod(int num, AsyncCallback callback, object state);
    int EndSomeMethod(IAsyncResult ar);
}

我的实际代码使用Task.Factory.FromAsync 创建一个任务,然后使用.net 4.5 中引入的新异步/等待模式等待这个任务。

我想测试我的类,因此我需要编写一个方法来接收模拟、开始方法、结束方法和返回值,并设置模拟以便最终返回所需的返回值。

示例用法:

SetupAsync(mock, mocked => mocked.BeginSomeMethod, mocked=> mocked.EndSomeMethod, 7);

这将导致带有任何 int 参数的异步流返回 7。 我似乎无法弄清楚如何在最小起订量中完成这样的事情。

【问题讨论】:

    标签: c# wcf asynchronous moq async-await


    【解决方案1】:

    首先,我建议您使用TaskWsdlImportExtension 创建基于Task 的异步WCF 代理。 VS2012 默认执行此操作,但您在 VS2010+AsyncCTP 上 have to set it up yourself。针对Task API 进行单元测试更容易。

    如果您确实想针对Begin/End 进行单元测试,我认为最简单的方法是使用基于Task 的模拟并公开Begin/End 端点。我的AsyncEx 库中的[AsyncFactory|AsyncFactory<T>].[ToBegin|ToEnd] 方法在Task 周围提供Begin/End 方法包装器,或者您可以查看Stephen Toub's blog post about writing these kinds of wrappers

    您可以从Task.FromResult 获取简单的已完成任务,也可以使用以下构造强制异步完成任务:

    Task.Run(async () => { await Task.Yield(); return 7; });
    

    (Async CTP 等效项是):

    TaskEx.RunEx(async () => { await TaskEx.Yield(); return 7; });
    

    我不完全确定如何将其与最小起订量联系起来。同样,我怀疑基于Task 的API 比Begin/End 更容易模拟。 Begin/End 有它自己的特殊语义(你必须传递正确的IAsyncResultEnd 必须为每个Begin 调用一次,等等),所以还有更多的东西要测试。

    【讨论】:

      猜你喜欢
      • 2012-08-15
      • 2012-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2015-07-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多