检查对于异步方法的Received()调用

let*_*tbe 18 c# asynchronous nsubstitute async-await

当我运行以下代码时:

[Test]
public async Task Can_Test_Update()
{
    var response = await _controller.UpdateAsync(Guid.NewGuid());
    response.Valid.Should().BeTrue();

    _commands.Received().UpdateAsync(
        Arg.Is<Something>(
            l => l.Status == Status.Updated)); 
}
Run Code Online (Sandbox Code Playgroud)

如果我在" await"之前添加" " _commands.Received().UpdateAsync,它会抛出一个空引用异常.我怎样才能阻止这种情况发生,或者await不是必要的?

let*_*tbe 16

我在这里找到了答案.

Received.InOrder(async () =>
{
    await _Commands.UpdateAsync(Arg.Is<Lobby>(l => l.Status == Status.Updated));
});
Run Code Online (Sandbox Code Playgroud)

  • 运行测试时,它会导致错误:“预计按顺序接收这些调用” (2认同)

Jak*_*van 6

当NSubstitute看到异步调用时,它会自动创建一个已完成的任务,因此await的工作方式与您在代码中的预期相同(而不是抛出NullReferenceException).在这种情况下,这将是_commands.UpdateAsync(Status.Updated))您正在测试的方法内部返回的任务.

.Received()另一方面,调用是验证异步方法是否被调用,即完全同步,因此不需要等待.

要记住的关键是异步方法返回一个Task.调用异步方法并返回任务是完全同步的,然后等待Task知道任务所代表的异步操作何时完成.

  • 问题是这会在控制台中留下一个难看的错误。[这个](/sf/answers/3393755501/)确实有效,但我还想指出[最小起订量更干净地处理这种情况](/sf/answers/639570501/ /542251) 如果你没有设置 nsubstitute (3认同)
  • 很好的答案,.Received()调用不需要等待。谢谢,杰克·金尼文 (2认同)

Gre*_*gas 6

显然你可以简单地使用await以下Received方法:

[Test]
public async Task Can_Test_Update()
{
    var response = await _controller.UpdateAsync(Guid.NewGuid());
    response.Valid.Should().BeTrue();

    await _commands.Received().UpdateAsync(
        Arg.Is<Something>(
            l => l.Status == Status.Updated)); 
}
Run Code Online (Sandbox Code Playgroud)


pip*_*omb 5

根据有关堆栈溢出的答案,从NSubstitute版本1.8.3开始,您可以使用await它,并且它将按预期工作,而不是抛出NullReferenceException。

我刚刚像在1.5.0版本上一样尝试了此方法,并按照您的描述获取了NullReferenceException,但是现在我使用的是最新版本(1.10.0),它运行良好。