Skip to content

Commit

Permalink
Add extensions method 'WithInnerExceptionExactly()' for async Excepti…
Browse files Browse the repository at this point in the history
…onAssertions
  • Loading branch information
LennartKoot committed Aug 20, 2021
1 parent a977427 commit 1d6b2a3
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
23 changes: 23 additions & 0 deletions Src/FluentAssertions/ExceptionAssertionsExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,29 @@ public static class ExceptionAssertionsExtensions
return (await task).WithInnerException<TInnerException>(because, becauseArgs);
}

/// <summary>
/// Asserts that the thrown exception contains an inner exception of the exact type <typeparamref name="TInnerException" /> (and not a derived exception type).
/// </summary>
/// <typeparam name="TException">The expected type of the exception.</typeparam>
/// <typeparam name="TInnerException">The expected type of the inner exception.</typeparam>
/// <param name="task">The <see cref="ExceptionAssertions{TException}"/> containing the thrown exception.</param>
/// <param name="because">
/// A formatted phrase as is supported by <see cref="string.Format(string,object[])" /> explaining why the assertion
/// is needed. If the phrase does not start with the word <i>because</i>, it is prepended automatically.
/// </param>
/// <param name="becauseArgs">
/// Zero or more objects to format using the placeholders in <paramref name="because" />.
/// </param>
public static async Task<ExceptionAssertions<TInnerException>> WithInnerExceptionExactly<TException, TInnerException>(
this Task<ExceptionAssertions<TException>> task,
string because = "",
params object[] becauseArgs)
where TException : Exception
where TInnerException : Exception
{
return (await task).WithInnerExceptionExactly<TInnerException>(because, becauseArgs);
}

/// <summary>
/// Asserts that the thrown exception has a parameter which name matches <paramref name="paramName" />.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,21 @@ public async Task When_async_method_throws_the_expected_inner_exception_it_shoul
await action.Should().NotThrowAsync();
}

[Fact]
public async Task When_async_method_throws_the_expected_inner_exception_exactly_it_should_succeed()
{
// Arrange
Func<Task> task = () => Throw.Async(new AggregateException(new ArgumentException()));

// Act
Func<Task> action = () => task
.Should().ThrowAsync<AggregateException>()
.WithInnerExceptionExactly<AggregateException, ArgumentException>();

// Assert
await action.Should().NotThrowAsync();
}

[Fact]
public async Task When_async_method_throws_aggregate_exception_containing_expected_exception_it_should_succeed()
{
Expand Down Expand Up @@ -875,6 +890,21 @@ public async Task When_async_method_does_not_throw_the_expected_inner_exception_
await action.Should().ThrowAsync<XunitException>().WithMessage("*InvalidOperation*Argument*");
}

[Fact]
public async Task When_async_method_does_not_throw_the_expected_inner_exception_exactly_it_should_fail()
{
// Arrange
Func<Task> task = () => Throw.Async(new AggregateException(new ArgumentNullException()));

// Act
Func<Task> action = () => task
.Should().ThrowAsync<AggregateException>()
.WithInnerExceptionExactly<AggregateException, ArgumentException>();

// Assert
await action.Should().ThrowAsync<XunitException>().WithMessage("*ArgumentException*ArgumentNullException*");
}

[Fact]
public async Task When_async_method_does_not_throw_the_expected_exception_it_should_fail()
{
Expand Down

0 comments on commit 1d6b2a3

Please sign in to comment.