JBo*_*ond 23 c# unit-testing asynchronous nsubstitute async-await
我试图验证使用正确的参数调用异步方法.但是,我得到警告:
"因为没有等待这个调用,所以当前方法的执行在调用完成之前继续.考虑将'await'运算符应用于调用的结果".此警告显示在//Assert
注释下方的代码行上(下方).
我使用NSubstitute的测试如下:
[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"));
}
Run Code Online (Sandbox Code Playgroud)
被测单元方法underTest.ExecuteAsync(request)
调用ExecuteProcedureAsync
并执行await:
var ds = await DatabaseHelper.ExecuteProcAsync(dbParams);
Run Code Online (Sandbox Code Playgroud)
由于使用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);
}
Run Code Online (Sandbox Code Playgroud)
我已经看到有一种解决方法,您可以添加扩展方法来删除问题:
public static class TestHelper
{
public static void IgnoreAwait(this Task task)
{
}
}
Run Code Online (Sandbox Code Playgroud)
这意味着我的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();
}
Run Code Online (Sandbox Code Playgroud)
但是,我认为必须有一个更好的解决方案吗?
Mar*_*ldi 21
只要您更新到1.9.0或更高版本,您就可以在await
不接收的情况下使用NullReferenceException
.
每当Received()
谓词变得太复杂或者与NSubstitute不匹配时,你总是可以通过或使用回调来捕获指定的args .对于你的用例,这将是这样的When().Do()
.AndDoes()
DatabaseParams receivedParms = null;
databaseHelperSub.ExecuteProcAsync(Arg.Any<DatabaseParams>())
.Returns(Task.FromResult((object)null))
.AndDoes(x => receivedParms = x.Arg<DatabaseParams>);
//Act
await underTest.ExecuteAsync(request);
//Assert
receivedParms.Should().NotBeNull();
// assert your parms...
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
11067 次 |
最近记录: |