xunit Assert.ThrowsAsync does not work properly?
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
Assert.ThrowsAsync<T> in xUnit verifies that an async method throws a specific exception type. The most common reason it "does not work" is that the test method does not await the Assert.ThrowsAsync call. Without await, the test runner sees a completed test (no exception) while the assertion runs in the background. The second common cause is passing a synchronous lambda instead of one that returns a Task. Both issues cause the test to pass incorrectly, hiding real bugs.
The Problem: Missing await
Assert.ThrowsAsync returns a Task<T>. If you do not await it, the test method returns before the assertion evaluates. The test runner sees no exception from the test method and marks it as passed.
Correct Usage Patterns
Assert.ThrowsAsync returns the caught exception, so you can inspect its properties (message, inner exception, custom fields) after awaiting.
ThrowsAsync vs ThrowsAnyAsync
Use ThrowsAsync<T> when you expect an exact exception type. Use ThrowsAnyAsync<T> when derived types should also satisfy the assertion.
Synchronous Exceptions in Async Methods
When an async method throws before its first await, the exception is captured in the returned Task. Assert.ThrowsAsync correctly handles this case.
Testing with async Lambdas
Record Pattern (Alternative)
Record.ExceptionAsync captures any exception without asserting its type, giving you full control over what to check.
Common Pitfalls
- Not awaiting Assert.ThrowsAsync: This is the number one cause of "it does not work." Without
await, the test method returns immediately and passes. The assertion runs as an unobserved Task. Alwaysawait Assert.ThrowsAsync<T>(...). - Using ThrowsAsync when a derived exception is thrown:
ThrowsAsync<ArgumentException>fails if the method throwsArgumentNullException(which derives fromArgumentException). UseThrowsAnyAsync<ArgumentException>to accept derived types. - Returning Task.CompletedTask from the lambda: If your lambda catches the exception internally or returns a non-faulted task,
ThrowsAsyncsees a successful completion and fails the test. Ensure the exception propagates into the returned Task. - Mixing Assert.Throws with async methods:
Assert.Throws<T>(synchronous) does not await the returned Task. It only catches exceptions thrown synchronously during Task creation. UseAssert.ThrowsAsync<T>for all async methods. - Compiler warning CS4014 (unawaited task): If you forget
await, the C# compiler warns "this call is not awaited." Treat CS4014 as an error in test projects by adding<WarningsAsErrors>CS4014</WarningsAsErrors>to your.csprojto catch missing awaits at build time.
Summary
- Always
awaitthe call toAssert.ThrowsAsync<T>()— without it, the test always passes - Use
ThrowsAsync<T>for exact exception types,ThrowsAnyAsync<T>for derived types - The lambda passed to
ThrowsAsyncmust return aTask(useasynclambda or return the async method call) - Use
Record.ExceptionAsyncwhen you need to inspect multiple properties of the caught exception - Enable CS4014 as a build error to catch missing
awaiton assertions at compile time
Related reading
- You Don't Know JS Async and Performance - cooperative concurrency?
- ZeroMQ How to handle non-message-related, asynchronous events in a ZeroMQ node?
- ZeroMQ Publish and Subscribe concurrently
- ZeroMQ Recommended pattern for inproc clients from multiple threads pushing ordered messages to a server?
- xUnit.net Global setup teardown?
- ZooKeeper session expired in tests
- You are not authorised to use this service iTunes app upload error
- You have not accepted the license agreements of the following SDK components
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.