2

在我们的Web API集成测试中,我们遇到了有关测试异步操作的问题。Web API - 拦截器 - 拦截异步控制器操作

在我的简单测试,我创建了一个简单的控制器操作:

[HttpGet] 
[Route("test")] 
public async Task<ApiResponse> Test() 
{ 
    return await Task.FromResult(new ApiResponse(true)); 
} 

然而,当我运行它下面的异常失败的集成测试:

System.InvalidCastException:无法投 'MoovShack.Api.Model.Shared.ApiModels.ApiResponse'类型的对象键入 'System.Threading.Tasks.Task`1 [MoovShack.Api.Model.Shared.ApiModels.ApiResponse]'。 在Castle.Proxies.IIdentityControllerProxy.Test()在 ServerApi.IntegrationTests.IdentityControllerTests.d__10.MoveNext() 在 E:\开发\ moovshack \ ServerApi.IntegrationTests \ IdentityControllerTests.cs:线 ---完从以前的位置,其中的例外是在 NUnit.Framework.Internal.AsyncInvocationRegion.AsyncTaskInvocationRegion.WaitForPendingOperationsToComplete(对象 invocationResult)在 NUnit.Framework抛出---在 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()堆栈跟踪。 Internal.Commands.TestMethodCommand.RunAsyncTestMethod(TestExecutionContext 上下文)

我可以看到这是来自哪里,因为我们正在返回一个结果,它不再与显然包含在任务中的动作返回类型匹配。

我们的拦截整个代码块运行正常:

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

我非常不确定从哪里去这里。

回答

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