在我们的Web API集成测试中,我们遇到了测试异步操作的问题。
在我的简单测试中,我创建了一个简单的控制器动作:
[HttpGet]
[Route("test")]
public async Task<ApiResponse> Test()
{
return await Task.FromResult(new ApiResponse(true));
}
但是当我运行集成测试时,它会因以下异常而失败:
System.InvalidCastException:无法转换类型的对象 'Jacobo.Api.Model.Shared.ApiModels.ApiResponse'键入 'System.Threading.Tasks.Task`1 [Jacobo.Api.Model.Shared.ApiModels.ApiResponse]'。 在Castle.Proxies.IIdentityControllerProxy.Test()at ServerApi.IntegrationTests.IdentityControllerTests.d__10.MoveNext() 在 E:\开发\雅各布\ ServerApi.IntegrationTests \ IdentityControllerTests.cs:行 218 ---从抛出异常的先前位置开始的堆栈跟踪结束--- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()at NUnit.Framework.Internal.AsyncInvocationRegion.AsyncTaskInvocationRegion.WaitForPendingOperationsToComplete(对象 invocationResult)at NUnit.Framework.Internal.Commands.TestMethodCommand.RunAsyncTestMethod(TestExecutionContext 上下文中)
我可以看到它来自何处,因为我们返回的结果不再与动作返回类型相匹配,该结果显然包含在任务中。
我们的Interceptor代码的整个块运行良好:
public void Intercept(IInvocation invocation)
{
// our interceptor implementation ...
// some irrelevant code before this
invocation.ReturnValue = webInvocation.Invoke(_client, invocation.Arguments); // the return value is populated correctly. not wrapped in a task.
}
然后测试失败,因为它试图返回等待的结果:
[Test]
public async Task GettingAsyncActionResultWillSucceed()
{
var ctl = BuildController(new SameMethodStack("GET"));
var result = await ctl.Test();
Assert.IsTrue(result.Success);
}
我不确定从哪里开始。
答案 0 :(得分:1)
终于找到了解决方案。我必须检测方法是否是异步的并且基于将结果包装到任务中:
if (isAsync)
{
var result = webInvocation.Invoke(_client, invocation.Arguments);
var type = result.GetType();
var methodInfo = typeof(Task).GetMethod("FromResult");
var genericMethod = methodInfo.MakeGenericMethod(type);
invocation.ReturnValue = genericMethod.Invoke(result, new []{ result });
}