我正在尝试验证是否使用正确的参数调用了异步方法。但是,我得到警告:
“由于未等待此调用,因此在调用完成之前将继续执行当前方法。请考虑将'await'运算符应用于调用结果”。该警告出现在//Assert
注释下方的代码行(如下)。
我使用 N替代进行的测试如下:
[Test]
public async Task SimpleTests()
{
//Arrange
var request = CreateUpdateItemRequest();
databaseHelperSub.ExecuteProcAsync(Arg.Any<DatabaseParams>()).Returns(Task.FromResult((object)null));
//Act
await underTest.ExecuteAsync(request);
//Assert
databaseHelperSub.Received().ExecuteProcAsync(Arg.Is<DatabaseParams>(
p => p.StoredProcName == StoredProcedureName
&& p.Parameters[0].ParameterName == "Param1"
&& p.Parameters[0].Value.ToString() == "Value1"
&& p.Parameters[1].ParameterName == "Param2"
&& p.Parameters[1].Value.ToString() == "Value2"));
}
被测单元方法
underTest.ExecuteAsync(request)
调用ExecuteProcedureAsync
并执行等待:var ds = await DatabaseHelper.ExecuteProcAsync(dbParams);
由于使用NSubstitute,在执行被测单元之后需要Received()。而在RhinoMocks中,您可以期望以便在执行被测单元之前发生调用。 RhinoMocks可以返回Task.FromResult(),而NSubstitute不能。
适用的RhinoMocks等效项是这样的:
[Test]
public async Task SimpleTest()
{
// Arrange
var request = new UpdateItemRequest();
databaseHelperMock.Expect(m => m.ExecuteProcAsync(Arg<DatabaseParams>.Matches(
p => p.StoredProcName == StoredProcedureName
&& p.Parameters[0].ParameterName == "Param1"
&& p.Parameters[0].Value.ToString() == "Value1"
&& p.Parameters[1].ParameterName == "Param2"
&& p.Parameters[1].Value.ToString() == "Value2
))).Return(Task.FromResult<object>(null));
// Act
await underTest.ExecuteAsync(request);
}
我已经看到有一种解决方法,可以在其中添加扩展方法来消除此问题:
public static class TestHelper
{
public static void IgnoreAwait(this Task task)
{
}
}
意味着我的 NSubstitute 的测试行可以按以下方式执行,并且警告消失了:
databaseHelperSub.Received().ExecuteProcAsync(Arg.Is<DatabaseParams>(
p => p.StoredProcName == StoredProcedureName
&& p.Parameters[0].ParameterName == "Param1"
&& p.Parameters[0].Value.ToString() == "Value1"
&& p.Parameters[1].ParameterName == "Param2"
&& p.Parameters[1].Value.ToString() == "Value2")).IgnoreAwait();
}
但是,我认为必须为此提供更好的解决方案?
最佳答案
一旦您更新到1.9.0或更高版本,就可以使用await
而不会收到NullReferenceException
。