Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,26 @@ uid: classic-assert-catch-async

# Assert.CatchAsync

**Assert.CatchAsync** is similar to [Assert.ThrowsAsync](Assert.ThrowsAsync.md) but will pass for an exception
that is derived from the one specified.
**Assert.CatchAsync** is similar to [Assert.ThrowsAsync](Assert.ThrowsAsync.md) but will pass for an exception that is derived from the one specified.

```csharp
Task<Exception> Assert.CatchAsync(Func<Task> asyncCode);
Task<Exception> Assert.CatchAsync(Func<Task> asyncCode,
string message, params object[] params);

Task<Exception> Assert.CatchAsync(Type expectedExceptionType, Func<Task> asyncCode);
Task<Exception> Assert.CatchAsync(Type expectedExceptionType, Func<Task> asyncCode,
string message, params object[] params);

Task<T> Assert.CatchAsync<T>(Func<Task> asyncCode);
Task<T> Assert.CatchAsync<T>(Func<Task> asyncCode,
string message, params object[] params);
```

## NUnit 4 and earlier

In NUnit 4 and earlier this assertion would not need to be awaited and would return the `Exception` or `TActual` instance directly. The callback to invoke would also be passed as an `AsyncTestDelegate` instead of a `Func<Task>`. These behaviors were both changed in NUnit 5 to better align the API with
modern .NET standards and conventions.

```csharp
Exception Assert.CatchAsync(AsyncTestDelegate code);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ uid: classic-assert-does-not-throw-async
**Assert.DoesNotThrowAsync** verifies that the delegate provided as an argument
does not throw an exception. See [Assert.DoesNotThrow](Assert.DoesNotThrow.md) for synchronous code.

```csharp
Task Assert.DoesNotThrowAsync(Func<Task> asyncCode);
Task Assert.DoesNotThrowAsync(Func<Task> asyncCode,
string message, params object[] params);
```

## NUnit 4 and earlier

In NUnit 4 and earlier this assertion would not need to be awaited and would return `void` instead of `Task`. The callback to invoke would also be passed as an `AsyncTestDelegate` instead of a `Func<Task>`. These behaviors were both changed in NUnit 5 to better align the API with
modern .NET standards and conventions.

```csharp
void Assert.DoesNotThrowAsync(AsyncTestDelegate code);
void Assert.DoesNotThrowAsync(AsyncTestDelegate code,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,36 @@ uid: classic-assert-throws-async
The **Assert.ThrowsAsync** is the async equivalent to [Assert.Throws](Assert.Throws.md)
for asynchronous code. See [Assert.Throws](Assert.Throws.md) for more information.

```csharp
Task<Exception> Assert.ThrowsAsync(Type expectedExceptionType, Func<Task> asyncCode);
Task<Exception> Assert.ThrowsAsync(Type expectedExceptionType, Func<Task> asyncCode,
string message, params object[] params);

Task<Exception> Assert.ThrowsAsync(IResolveConstraint constraint, Func<Task> asyncCode);
Task<Exception> Assert.ThrowsAsync(IResolveConstraint constraint, Func<Task> asyncCode,
string message, params object[] params);

Task<TActual> Assert.ThrowsAsync<TActual>(Func<Task> asyncCode);
Task<TActual> Assert.ThrowsAsync<TActual>(Func<Task> asyncCode,
string message, params object[] params);
```

In the above code `Func<Task>` is an async delegate, which is used to execute the code
in question. This will likely be a lambda expression.

The following example shows the most common way of writing tests.

[!code-csharp[AssertThrowsAsync](~/snippets/Snippets.NUnit/AssertThrowsAsync.cs#AssertThrowsAsync)]

This example shows use of the return value to perform additional verification of the exception.

[!code-csharp[AssertThrowsAsync](~/snippets/Snippets.NUnit/AssertThrowsAsync.cs#UsingReturnValue)]

## NUnit 4 and earlier

In NUnit 4 and earlier this assertion would not need to be awaited and would return the `Exception` or `TActual` instance directly. The callback to invoke would also be passed as an `AsyncTestDelegate` instead of a `Func<Task>`. These behaviors were both changed in NUnit 5 to better align the API with
modern .NET standards and conventions.

```csharp
Exception Assert.ThrowsAsync(Type expectedExceptionType, AsyncTestDelegate code);
Exception Assert.ThrowsAsync(Type expectedExceptionType, AsyncTestDelegate code,
Expand All @@ -21,18 +51,44 @@ TActual Assert.ThrowsAsync<TActual>(AsyncTestDelegate code,
string message, params object[] params);
```

In the above code **AsyncTestDelegate** is a delegate of the form
**Task AsyncTestDelegate()**, which is used to execute the code
in question. This will likely be a lambda expression.
For example:

The following example shows the most common way of writing tests.
The following example shows the previous way to simply assert that an exception of a given type was thrown.

[!code-csharp[AssertThrowsAsync](~/snippets/Snippets.NUnit/AssertThrowsAsync.cs#AssertThrowsAsync)]
```csharp
[Test]
public void Tests()
{
// Using a method as a delegate
Assert.ThrowsAsync<ArgumentException>(async () => await MethodThatThrows());
}

This example shows use of the return value to perform
additional verification of the exception. Note that you do not need to await the result.
private async Task MethodThatThrows()
{
await Task.Delay(100);
throw new ArgumentException();
}

[!code-csharp[AssertThrowsAsync](~/snippets/Snippets.NUnit/AssertThrowsAsync.cs#UsingReturnValue)]
```

This example shows use of the return value to perform additional verification of the exception.

```csharp
[Test]
public void TestException()
{
MyException ex = Assert.ThrowsAsync<MyException>(async () => await MethodThatThrows());

Assert.That(ex.Message, Is.EqualTo("message"));
Assert.That(ex.MyParam, Is.EqualTo(42));
}

private async Task MethodThatThrows()
{
await Task.Delay(100);
throw new MyException("message", 42);
}
```

## See Also

Expand Down
8 changes: 4 additions & 4 deletions docs/snippets/Snippets.NUnit/AssertThrowsAsync.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ public class AssertThrowsAsync
public class AssertThrowsTests
{
[Test]
public void Tests()
public async Task Tests()
{
// Using a method as a delegate
Assert.ThrowsAsync<ArgumentException>(async () => await MethodThatThrows());
await Assert.ThrowsAsync<ArgumentException>(async () => await MethodThatThrows());
}

private async Task MethodThatThrows()
Expand All @@ -32,9 +32,9 @@ private async Task MethodThatThrows()
public class UsingReturnValue
{
[Test]
public void TestException()
public async Task TestException()
{
MyException ex = Assert.ThrowsAsync<MyException>(async () => await MethodThatThrows());
MyException ex = await Assert.ThrowsAsync<MyException>(async () => await MethodThatThrows());

Assert.That(ex.Message, Is.EqualTo("message"));
Assert.That(ex.MyParam, Is.EqualTo(42));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public void WhiteSpaceConstraint_Examples()
Assert.That("", Is.WhiteSpace); // Empty string
Assert.That(" ", Is.WhiteSpace); // Space
Assert.That(" \t\n", Is.WhiteSpace); // Mixed whitespace
Assert.That(null, Is.WhiteSpace); // Null
Assert.That((string?)null, Is.WhiteSpace); // Null

Assert.That("Hello", Is.Not.WhiteSpace);
Assert.That(" Hello ", Is.Not.WhiteSpace); // Has non-whitespace content
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void InstanceOfTypeConstraint_Examples()

// Negative tests
Assert.That("Hello", Is.Not.InstanceOf<int>());
Assert.That(null, Is.Not.InstanceOf<string>()); // null is not an instance of any type
Assert.That((string?)null, Is.Not.InstanceOf<string>()); // null is not an instance of any type
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This resolved an overload ambiguity. The compiler seemed to want to resolve to the Action overload

}
#endregion

Expand Down
2 changes: 1 addition & 1 deletion docs/snippets/Snippets.NUnit/Snippets.NUnit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageReference Include="NUnit" Version="4.6.0-*" />
<PackageReference Include="NUnit" Version="5.0.0-alpha.100.9" />
<PackageReference Include="NUnit3TestAdapter" Version="6.2.0" />
<PackageReference Include="NUnit.Analyzers" Version="4.13.0">
<PrivateAssets>all</PrivateAssets>
Expand Down
Loading