C# NSubstitute-接收异步-“;未等待呼叫”;警告
我试图验证是否使用正确的参数调用了异步方法。然而,我得到了警告:C# NSubstitute-接收异步-“;未等待呼叫”;警告,c#,unit-testing,asynchronous,async-await,nsubstitute,C#,Unit Testing,Asynchronous,Async Await,Nsubstitute,我试图验证是否使用正确的参数调用了异步方法。然而,我得到了警告: ”由于此调用没有等待,当前方法的执行在调用完成之前继续。请考虑将“Acess”运算符应用到调用的结果中。此警告出现在//Assert注释(下面)下面的代码行上 我使用NSubstitute进行的测试如下: [Test] public async Task SimpleTests() { //Arrange var request = CreateUpdateItemRequest(); databaseHelperS
”由于此调用没有等待,当前方法的执行在调用完成之前继续。请考虑将“Acess”运算符应用到调用的结果中。此警告出现在
//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"));
}
由于使用NSubstitute,在执行被测单元之后需要Received()。而在Rhinomock中,您可以期望在执行测试单元之前发生调用。Rhinomock可以返回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);
}
这意味着我的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();
}
databaseHelperSub.Received().ExecuteLocasync(Arg.Is(
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();
}
但是,我认为一定有更好的解决方案?每当
Received()
谓词变得太复杂或与NSubstitute不匹配时,您可以始终使用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...
DatabaseParams receivedParms=null;
databaseHelperSub.ExecuteLocasync(Arg.Any())
.Returns(Task.FromResult((对象)null))
.AndDoes(x=>receivedParms=x.Arg);
//表演
等待测试不足。ExecuteAsync(请求);
//断言
receivedParms.Should().NotBeNull();
//坚持你的观点。。。
一旦更新到1.9.0版或更高版本,您就可以使用wait
而不必接收NullReferenceException
说明for Received wait不是必需的,但是编译器不理解它
您可以安全地抑制该警告
#pragma warning disable 4014 //for .Received await is not required, so suppress warning “Consider applying the 'await' operator”
_service.Received(totalNumber).MyMethod(Arg.Any<ParamType>());
#pragma warning restore 4014
<代码> >语用障碍警告禁用4014 / /。接收等待不是必需的,因此禁止警告“考虑应用‘等待’操作符”。
_service.Received(totalNumber).MyMethod(Arg.Any());
#pragma警告恢复4014
这是一个编译器警告,说明您忘记在异步方法之前放置
wait
。如果在调用之前放置wait,为什么不在//Assert
之后的行中放置wait
。测试失败,因为它接收到空引用异常。NSubstitute目前没有更好的方法来处理此问题。请看Jake在这里的解释:可能值得NSub更改,我在这里提出了一个问题:可能与上下文无关,但我仍然想推荐Moq
。。看起来你可以使用Moq.Verify()你知道1.8.3什么时候发布吗?我现在有这个问题,我不知道。不过你应该问问大卫·切帕克(也许是通过)。他是NSubstitute的维护者。@levelis正是你所知道的。NSubstitute的V1.9.0现已发布。其中包含的增强功能将解决此堆栈溢出问题。
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...
#pragma warning disable 4014 //for .Received await is not required, so suppress warning “Consider applying the 'await' operator”
_service.Received(totalNumber).MyMethod(Arg.Any<ParamType>());
#pragma warning restore 4014