diff --git a/Src/FluentAssertions/AssertionExtensions.Actions.cs b/Src/FluentAssertions/AssertionExtensions.Actions.cs
index 1258b18ae1..8b33fd771b 100644
--- a/Src/FluentAssertions/AssertionExtensions.Actions.cs
+++ b/Src/FluentAssertions/AssertionExtensions.Actions.cs
@@ -64,6 +64,32 @@ public static partial class AssertionExtensions
return exceptionAssertions;
}
+ ///
+ /// Asserts that the subject throws the exact exception (and not a derived exception type).
+ ///
+ /// A reference to the method or property.
+ ///
+ /// The type of the exception it should throw.
+ ///
+ ///
+ /// A formatted phrase explaining why the assertion should be satisfied. If the phrase does not
+ /// start with the word because, it is prepended to the message.
+ ///
+ ///
+ /// Zero or more values to use for filling in any compatible placeholders.
+ ///
+ ///
+ /// Returns an object that allows asserting additional members of the thrown exception.
+ ///
+ public static async Task> ThrowExactlyAsync(this AsyncFunctionAssertions asyncActionAssertions, string because = "",
+ params object[] becauseArgs)
+ where TException : Exception
+ {
+ var exceptionAssertions = await asyncActionAssertions.ThrowAsync(because, becauseArgs);
+ exceptionAssertions.Which.GetType().Should().Be(because, becauseArgs);
+ return exceptionAssertions;
+ }
+
private class AggregateExceptionExtractor : IExtractExceptions
{
public IEnumerable OfType(Exception actualException)
diff --git a/Tests/Shared.Specs/AsyncFunctionExceptionAssertionSpecs.cs b/Tests/Shared.Specs/AsyncFunctionExceptionAssertionSpecs.cs
index 00b2502752..09ed56561e 100644
--- a/Tests/Shared.Specs/AsyncFunctionExceptionAssertionSpecs.cs
+++ b/Tests/Shared.Specs/AsyncFunctionExceptionAssertionSpecs.cs
@@ -171,6 +171,64 @@ public async Task When_async_method_does_not_throw_async_exception_and_that_was_
await action.Should().NotThrowAsync();
}
+ [Fact]
+ public async Task When_subject_throws_subclass_of_expected_async_exception_it_should_succeed()
+ {
+ //-----------------------------------------------------------------------------------------------------------
+ // Arrange
+ //-----------------------------------------------------------------------------------------------------------
+ var asyncObject = new AsyncClass();
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Act
+ //-----------------------------------------------------------------------------------------------------------
+ Func action = async () => await asyncObject.ThrowAsync();
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Assert
+ //-----------------------------------------------------------------------------------------------------------
+ await action.Should().ThrowAsync("because {0} should do that", "IFoo.Do");
+ }
+
+ [Fact]
+ public async Task When_subject_throws_subclass_of_expected_async_exact_exception_it_should_throw()
+ {
+ //-----------------------------------------------------------------------------------------------------------
+ // Arrange
+ //-----------------------------------------------------------------------------------------------------------
+ var asyncObject = new AsyncClass();
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Act
+ //-----------------------------------------------------------------------------------------------------------
+ Func action = async () => await asyncObject.ThrowAsync();
+ Func testAction = async () => await action.Should().ThrowExactlyAsync("ABCDE");
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Assert
+ //-----------------------------------------------------------------------------------------------------------
+ (await testAction.Should().ThrowAsync()).WithMessage("*ArgumentException*ABCDE*ArgumentNullException*");
+ }
+
+ [Fact]
+ public async Task When_subject_throws_expected_async_exact_exception_it_should_succeed()
+ {
+ //-----------------------------------------------------------------------------------------------------------
+ // Arrange
+ //-----------------------------------------------------------------------------------------------------------
+ var asyncObject = new AsyncClass();
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Act
+ //-----------------------------------------------------------------------------------------------------------
+ Func action = async () => await asyncObject.ThrowAsync();
+
+ //-----------------------------------------------------------------------------------------------------------
+ // Assert
+ //-----------------------------------------------------------------------------------------------------------
+ await action.Should().ThrowExactlyAsync("because {0} should do that", "IFoo.Do");
+ }
+
[Fact]
public void When_async_method_throws_exception_and_no_exception_was_expected_it_should_fail()
{