From 776d5594d9834e68e3a45dfcadd9eda916b625c8 Mon Sep 17 00:00:00 2001 From: stevenaw Date: Fri, 29 May 2026 12:14:04 -0400 Subject: [PATCH 1/4] Update throwsasync --- .../classic-assertions/Assert.ThrowsAsync.md | 72 ++++++++++++++++--- .../Snippets.NUnit/AssertThrowsAsync.cs | 8 +-- .../Constraints/StringConstraintSnippets.cs | 2 +- .../Constraints/TypeConstraintSnippets.cs | 2 +- .../Snippets.NUnit/Snippets.NUnit.csproj | 2 +- 5 files changed, 71 insertions(+), 15 deletions(-) diff --git a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md index 7c160e4de..3935b0120 100644 --- a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md +++ b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md @@ -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 Assert.ThrowsAsync(Type expectedExceptionType, Func asyncCode); +Task Assert.ThrowsAsync(Type expectedExceptionType, Func asyncCode, + string message, params object[] params); + +Task Assert.ThrowsAsync(IResolveConstraint constraint, Func asyncCode); +Task Assert.ThrowsAsync(IResolveConstraint constraint, Func asyncCode, + string message, params object[] params); + +Task Assert.ThrowsAsync(Func asyncCode); +Task Assert.ThrowsAsync(Func asyncCode, + string message, params object[] params); +``` + +In the above code **Func** 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)] + +## Behavior in 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`. 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, @@ -21,18 +51,44 @@ TActual Assert.ThrowsAsync(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(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(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 diff --git a/docs/snippets/Snippets.NUnit/AssertThrowsAsync.cs b/docs/snippets/Snippets.NUnit/AssertThrowsAsync.cs index a145f8e27..97385d566 100644 --- a/docs/snippets/Snippets.NUnit/AssertThrowsAsync.cs +++ b/docs/snippets/Snippets.NUnit/AssertThrowsAsync.cs @@ -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(async () => await MethodThatThrows()); + await Assert.ThrowsAsync(async () => await MethodThatThrows()); } private async Task MethodThatThrows() @@ -32,9 +32,9 @@ private async Task MethodThatThrows() public class UsingReturnValue { [Test] - public void TestException() + public async Task TestException() { - MyException ex = Assert.ThrowsAsync(async () => await MethodThatThrows()); + MyException ex = await Assert.ThrowsAsync(async () => await MethodThatThrows()); Assert.That(ex.Message, Is.EqualTo("message")); Assert.That(ex.MyParam, Is.EqualTo(42)); diff --git a/docs/snippets/Snippets.NUnit/Constraints/StringConstraintSnippets.cs b/docs/snippets/Snippets.NUnit/Constraints/StringConstraintSnippets.cs index bd55a15f5..03aaf4f67 100644 --- a/docs/snippets/Snippets.NUnit/Constraints/StringConstraintSnippets.cs +++ b/docs/snippets/Snippets.NUnit/Constraints/StringConstraintSnippets.cs @@ -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 diff --git a/docs/snippets/Snippets.NUnit/Constraints/TypeConstraintSnippets.cs b/docs/snippets/Snippets.NUnit/Constraints/TypeConstraintSnippets.cs index 16aa4be63..7845ea592 100644 --- a/docs/snippets/Snippets.NUnit/Constraints/TypeConstraintSnippets.cs +++ b/docs/snippets/Snippets.NUnit/Constraints/TypeConstraintSnippets.cs @@ -25,7 +25,7 @@ public void InstanceOfTypeConstraint_Examples() // Negative tests Assert.That("Hello", Is.Not.InstanceOf()); - Assert.That(null, Is.Not.InstanceOf()); // null is not an instance of any type + Assert.That((string?)null, Is.Not.InstanceOf()); // null is not an instance of any type } #endregion diff --git a/docs/snippets/Snippets.NUnit/Snippets.NUnit.csproj b/docs/snippets/Snippets.NUnit/Snippets.NUnit.csproj index e51bb029b..bf290b9ea 100644 --- a/docs/snippets/Snippets.NUnit/Snippets.NUnit.csproj +++ b/docs/snippets/Snippets.NUnit/Snippets.NUnit.csproj @@ -10,7 +10,7 @@ - + all From 78f7e134bdd260baf41ea00ea445bbe4f4b036cc Mon Sep 17 00:00:00 2001 From: stevenaw Date: Fri, 29 May 2026 12:17:35 -0400 Subject: [PATCH 2/4] Update catchasync --- .../classic-assertions/Assert.CatchAsync.md | 22 +++++++++++++++++-- .../classic-assertions/Assert.ThrowsAsync.md | 2 +- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.CatchAsync.md b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.CatchAsync.md index 58d8c2101..5009ad50e 100644 --- a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.CatchAsync.md +++ b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.CatchAsync.md @@ -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 Assert.CatchAsync(Func asyncCode); +Task Assert.CatchAsync(Func asyncCode, + string message, params object[] params); + +Task Assert.CatchAsync(Type expectedExceptionType, Func asyncCode); +Task Assert.CatchAsync(Type expectedExceptionType, Func asyncCode, + string message, params object[] params); + +Task Assert.CatchAsync(Func asyncCode); +Task Assert.CatchAsync(Func 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`. 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); diff --git a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md index 3935b0120..c134fd420 100644 --- a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md +++ b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md @@ -32,7 +32,7 @@ This example shows use of the return value to perform additional verification of [!code-csharp[AssertThrowsAsync](~/snippets/Snippets.NUnit/AssertThrowsAsync.cs#UsingReturnValue)] -## Behavior in NUnit 4 and earlier +## 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`. These behaviors were both changed in NUnit 5 to better align the API with modern .NET standards and conventions. From b1b724a193369080d2f030be15205cabd856688a Mon Sep 17 00:00:00 2001 From: stevenaw Date: Fri, 29 May 2026 12:21:56 -0400 Subject: [PATCH 3/4] Update 'DoesNotThrowAsync' --- .../classic-assertions/Assert.DoesNotThrowAsync.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.DoesNotThrowAsync.md b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.DoesNotThrowAsync.md index 39e461c5c..29ec890eb 100644 --- a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.DoesNotThrowAsync.md +++ b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.DoesNotThrowAsync.md @@ -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 asyncCode); +Task Assert.DoesNotThrowAsync(Func 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`. 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, From b2f1ec3b49274a19507278bdd1ba4e366f0cffdb Mon Sep 17 00:00:00 2001 From: stevenaw Date: Fri, 29 May 2026 12:43:26 -0400 Subject: [PATCH 4/4] Fix linting issues --- .../assertions/classic-assertions/Assert.ThrowsAsync.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md index c134fd420..ec9d0accc 100644 --- a/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md +++ b/docs/articles/nunit/writing-tests/assertions/classic-assertions/Assert.ThrowsAsync.md @@ -21,7 +21,7 @@ Task Assert.ThrowsAsync(Func asyncCode, string message, params object[] params); ``` -In the above code **Func** is an async delegate, which is used to execute the code +In the above code `Func` 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.