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