question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Very easy to misuse `ThrowAsync` in a sync test

See original GitHub issue

Description

The API for asserting exceptions in async code is VERY easy to misuse. Such tests would pass, but in fact should fail.

The problem is that action.Should().ThrowAsync<Exception>() should be awaited, but Roslyn doesn’t know that and doesn’t warn you. It’s very easy to forget to put it in an async test, and to await it.

Complete minimal example reproducing the issue

This test has a very subtle hard-to-detect bug. It should fail, but will actually pass.

[Fact]
public void sync_test_that_should_fail_but_will_pass()
{
    Func<Task> action = () => throw new ArgumentNullException("paramName");
    action.Should().ThrowAsync<ArgumentNullException>().WithParameterName("foo");     // "foo" is incorrect
}

This test fixes the bug. It should fail, and will fail.

[Fact]
public async Task async_test_that_should_fail_and_will_fail()
{
    Func<Task> action = () => throw new ArgumentNullException("paramName");
    await action.Should().ThrowAsync<ArgumentNullException>().WithParameterName("foo");
}

Expected behavior:

Don’t know! 😄

Firstly please tell me, are you aware of an analyser (third party maybe?) that checks for this?

If not, there are two options:

  • Maybe someone someday will write an analyser that detects this problem. That would be best. It would see that you don’t await when calling a ThrowsAsync. I know nothing about Roslyn so regrettably cannot assist.
  • Is it possible to detect this at runtime and log a warning to the console?

Actual behavior:

Doesn’t warn you.

Versions

  • Which version of Fluent Assertions are you using? 6.2.0
  • Which .NET runtime and version are you targeting? .NET Core 5

Additional Information

Maybe there’s a different way to handle this problem - if so I’d appreciate the advice!

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Reactions:1
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
lonix1commented, Jan 5, 2022

Excellent blog article Dennis!

Read more comments on GitHub >

github_iconTop Results From Across the Web

c# - How can I unit test this async method which (correctly) ...
The problem is that your assertion framework does not understand asynchronous methods. I recommend you raise an issue with them.
Read more >
Mocking exceptions rising inside an async method
I'd like to have a test that checks what happens if, in the call to the GetAllAsync method of the service, an exception...
Read more >
Testing-library: avoid these mistakes in async tests
Await with sync methods. Simple asynchronous request. This is the most common mistake I'm running into while refactoring code.
Read more >
Untitled
On my unit tests i am using fluent assertions. ... Wiki Security Insights New issue Very easy to misuse ThrowAsync in a sync...
Read more >
Unit testing Swift code that uses async/await
Let's take a look at how to call async APIs within our unit tests, and also how async/await can be a great testing...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found