1

I used FluentAssertions; it's great! :) I particularly like using the .Invoking().Should().Throw<Exception>() pattern it provides.

I wrote this line in my test:

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

Where .SomeAsyncFunc is declared using the async keyword and makes use of the await keyword internally.

And it all passed, and I was very happy. And then I thought to verify that the test was doing what I thought it did, so I added code to force SomeAsyncFunc() to immediately throw. (before hitting any await keywords).

It still passed. This made me sad :(

I tried the following formulations, all of which also passed:

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();

Whereas is if I do this, then it DOES work ... but that feels very wrong!

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

What have I mis-understood?

Brondahl
  • 7,402
  • 5
  • 45
  • 74
  • Btw, the line you say 'works', doesn't really. The method returns a Task which likely hasn't executed.. But sans an await in the test it wouldn't throw anyways (unless you throw any exceptions prior to the first await of the method) – pinkfloydx33 Jun 26 '20 at 20:23

2 Answers2

3

I'm a moron.

.NotThrowAsync() is itself an async method, and thus needs to be awaited to work properly.

To allow that I needed to make my test async too:

//    |*This bit*|
public async Task SomeAsyncFunc_UnderRelevantConditions_DoesNotThrow()
{
    // ... Do Setup.
    
    await myObject.Invoking(r => r.SomeAsyncFunc()).Should().NotThrowAsync();
}

Brondahl
  • 7,402
  • 5
  • 45
  • 74
3

You need to combine the right things. So either use the synchronous version:

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

or go all the away async:

await myObject.Awaiting(r => r.SomeAsyncFunc()).Should().NotThrowAsync();
Dennis Doomen
  • 8,368
  • 1
  • 32
  • 44
  • What is the difference between `.Invoking` and `.Awaiting`, the docs don't really seem to spell it out? – Brondahl Jun 27 '20 at 14:23