我如何误用 NotThrowAsync

Posted

技术标签:

【中文标题】我如何误用 NotThrowAsync【英文标题】:How am I mis-using NotThrowAsync 【发布时间】:2020-10-17 09:28:01 【问题描述】:

我使用了 FluentAssertions;这很棒! :) 我特别喜欢使用它提供的.Invoking().Should().Throw<Exception>() 模式。

我在测试中写了这一行:

myObject.Invoking(r => r.SomeAsyncFunc()).Should().NotThrowAsync();

其中.SomeAsyncFunc 使用async 关键字声明,并在内部使用await 关键字。

一切都过去了,我很高兴。然后我想验证测试是否在做我认为的事情,所以我添加了代码来强制SomeAsyncFunc() 立即抛出。 (在点击任何 await 关键字之前)。

还是过去了。这让我很难过:(

我尝试了以下配方,都通过了:

myObject.Invoking(r => r.SomeAsyncFunc()).Should().NotThrowAsync();
myObject.Invoking(async r => await r.SomeAsyncFunc()).Should().NotThrowAsync();
myObject.Awaiting(r => r.SomeAsyncFunc()).Should().NotThrowAsync();
myObject.Awaiting((Func<MyObject, Task>)(async r => await r.SomeAsyncFunc())).Should().NotThrowAsync();

如果我这样做,那么它确实有效......但感觉很不对劲!

myObject.Invoking(r => r.SomeAsyncFunc()).Should().NotThrow();

我误解了什么?

【问题讨论】:

顺便说一句,你说“有效”的那一行,并不是真的。该方法返回一个可能尚未执行的任务。但是在测试中没有等待它无论如何都不会抛出(除非您在该方法的第一次等待之前抛出任何异常) 【参考方案1】:

我是个白痴。

.NotThrowAsync() 本身是一个async 方法,因此需要awaited 才能正常工作。

为了让我也需要进行测试async

//    |*This bit*|
public async Task SomeAsyncFunc_UnderRelevantConditions_DoesNotThrow()

    // ... Do Setup.
    
    await myObject.Invoking(r => r.SomeAsyncFunc()).Should().NotThrowAsync();


【讨论】:

【参考方案2】:

你需要结合正确的东西。所以要么使用同步版本:

myObject.Awaiting(r => r.SomeAsyncFunc()).Should().NotThrow();

要么走开async

await myObject.Awaiting(r => r.SomeAsyncFunc()).Should().NotThrowAsync();

【讨论】:

.Invoking.Awaiting 之间有什么区别,文档似乎并没有明确说明?

以上是关于我如何误用 NotThrowAsync的主要内容,如果未能解决你的问题,请参考以下文章

缓存同步如何保证缓存一致性缓存误用

讨论:缓存同步如何保证缓存一致性缓存误用

缓存同步如何保证缓存一致性缓存误用!

关于 MVC 的一个常见的误用

5 种常见的 async/await 误用 #yyds干货盘点#

关于JAVA中的Synchronization和interface误用