如何模拟任务<>结果?

Dav*_*vid 38 c# rhino-mocks task-parallel-library

我正在设置一些单元测试并使用Rhino Mocks填充正在测试的对象.被模拟的事情之一是Task<HttpResponseMessage>,因为被测试的逻辑包括HttpClient对获取异步响应的调用.

所以我开始设置这样的模拟:

var httpClient = MockRepository.GenerateMock<HttpClient>();
var taskFunc = MockRepository.GenerateMock<Func<HttpResponseMessage>>();
var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
var response = MockRepository.GenerateMock<HttpResponseMessage>();

httpClient.Stub(c => c.PostAsJsonAsync<IEnumerable<LogMessage>>(Arg<string>.Is.Anything, Arg<IEnumerable<LogMessage>>.Is.Anything)).Return(responseTask);
responseTask.Stub(t => t.Result).Return(response);
response.Stub(r => r.IsSuccessStatusCode).Return(true);
Run Code Online (Sandbox Code Playgroud)

(测试的"行为"步骤是实例化被测对象,将其提供给它httpClient,并在其上运行一个方法."断言"将通过模拟验证对它们进行了预期的方法调用.)

在调试器中单步执行此操作,此行上有一个无限期挂起:

responseTask.Stub(t => t.Result).Return(response);
Run Code Online (Sandbox Code Playgroud)

我没有很多使用Rhino Mocks或C#异步的经验,所以我可能会忽略一些明显的东西.当然,目标是对.Result财产的任何调用都将返回response模拟.但看起来我的尝试本身也许正在调用.Result我期望无限期等待,因为它只是一个模拟,也许?

安排这个的正确方法是什么?基本上我需要为我的对象提供一个模拟HttpClient并声明一个方法是用一个特定的参数调用它的.

Lee*_*Lee 61

最简单的方法就是返回一个包含预期结果的已完成任务:

var responseTask = Task.FromResult(response);
Run Code Online (Sandbox Code Playgroud)

我想这个悬挂的原因是模拟的任务永远不会启动,因此给定的func不会运行.您可以在测试中启动它:

var responseTask = MockRepository.GenerateMock<Task<HttpResponseMessage>>(taskFunc);
responseTask.Start();
Run Code Online (Sandbox Code Playgroud)

但是,由于您可以直接轻松创建已完成/失败/已取消的任务,因此没有理由模拟任务.