Comments (9)
@JohanLarsson I believe the problem with that approach is the method can never throw in that form. Even if the expression fails (and throws an exception), the exception will be thrown on a different thread and terminate the test process without properly reporting results. If we were to special case this, it would more likely need to be making it an error since it's not behaving anything close to what the user expects.
from asyncusageanalyzers.
Which case is this?
- The method does not have an
async void
signature, but it's reporting a warning anyway (false positive) - The method does have an
async void
signature, but this is a case where you commonly want to use this signature (intentional)
from asyncusageanalyzers.
It is 2 I think, we are stuck with NUnit 2.6.4 for reasons and it gets nasty to suppress these calls all over the place. Don't love suppressing per file.
The case would be to specialcase Assert.Xyz(...)
to allow it.
from asyncusageanalyzers.
Try:
[Test]
public void ShouldThrow()
{
var exception = Assert.Throws<Exception>(async () => await Task.Run(() => { throw new Exception("message"); }).ConfigureAwait(false));
Assert.AreEqual("message", exception.Message);
}
[Test]
public void ShouldNotThrow()
{
Assert.DoesNotThrow(async () => await Task.Run(() => { throw new Exception("message"); }).ConfigureAwait(false));
}
Using NUnit.2.6.4
from asyncusageanalyzers.
@JohanLarsson : are you sure NUnit doesn't offer a ThrowsAsync
method that you should await, like this?
var exception = await Assert.ThrowsAsync<Exception>(async () => await Task.Run(() => { throw new Exception("message"); }).ConfigureAwait(false));
Otherwise, as @sharwell said, exceptions are never thrown from methods with async in their signature. If NUnit recognizes Func specifically in its Throws
method, then it might work, if NUnit were willing to synchronously block the calling thread while invoking that delegate, but that could cause deadlocks for other reasons, and would slow down concurrent test execution where applicable.
from asyncusageanalyzers.
/cc @jnm2
from asyncusageanalyzers.
Thanks Sam! @JohanLarsson You're using NUnit 2 which actually has this concept of invoking an async void method and then waiting for it to complete by having installed a spying SynchronizationContext. This is a low-fi substitute for awaiting an awaitable object like Task, behaving close enough if you squint. This was removed in NUnit 3. If you were running NUnit 3.0+, that code would error at runtime, telling you to use DoesNotThrowAsync
.
My perfectionist side really hates the thought of turning off this insightful nag for all classes named Assert
, especially for the sake of such a legacy version of NUnit. If a framework makes you do something yucky (await async void), let's try all options for upgrading the framework before turning off the warning light.
You say you can't upgrade though and that's something we take seriously. In the meantime, how's this workaround?
internal static class AssertUtils
{
public static void DoesNotThrow(Func<Task> function)
{
if (function == null) throw new ArgumentNullException(nameof(function));
// Suppress once per project.
NUnit.Framework.Assert.DoesNotThrow(async () => await function.Invoke());
}
}
Or even more drop-in, if you can handle this (ReSharper will suggest 'simplifying' your access of all the other Assert methods):
internal static class Assert : NUnit.Framework.Assert
{
public new static void DoesNotThrow(Func<Task> function)
{
if (function == null) throw new ArgumentNullException(nameof(function));
// Suppress once per project.
NUnit.Framework.Assert.DoesNotThrow(async () => await function.Invoke());
}
}
from asyncusageanalyzers.
To @AArnott's point:
NUnit's Assert.DoesNotThrowAsync
is currently doing sync-over-async for historical reasons. As of NUnit 3.11, this won't deadlock for recognized SynchronizationContexts. But it's one thing for the framework to do sync-over-async with the entry point, the test method itself—this is exactly like async Task Main
—and it's quite another thing for Assert.*Async
to be doing sync-over-async as well. I've been thinking through ways to fix this; perhaps deprecate these sync-over-async APIs and introduce AssertAsync
.
Almost opened an issue on this two weeks ago. Given Sam's ping, I think I'll go ahead and do that.
from asyncusageanalyzers.
If anyone is interested, I've opened the issue.
from asyncusageanalyzers.
Related Issues (20)
- New rule proposal: Propagate cancellation tokens HOT 7
- Update IncludeCancellationParameter analyzer to check overloads
- Update IncludeCancellationParameter analyzer to cache context lookups
- Document IncludeCancellationParameter diagnostic
- Support Supression attribute HOT 3
- Update documentation to include [SuppressMessage] examples HOT 2
- Code fixes from AsyncUsageAnalyzers.CodeFixes don't work in Visual Studio
- Don't provide code fixes for Visual Basic in UseConfigureAwaitCodeFixProvider and DontUseThreadSleepCodeUniversalCodeFixProvider
- Add special rule for async void eventhandlers. HOT 1
- Await inside usings. HOT 4
- Refactor issue for ignoring a rule HOT 1
- Support Main with async
- Bug: Analyser not raising warnings for local functions not ending with "Async". HOT 1
- ValueTask<long[]> DeleteAsync
- AvoidAsyncSuffix misfires on ValueTask<T> returning methods HOT 1
- Treat types marked with AsyncMethodBuilderAttribute as asynchronous
- Treat methods with awaitable return types as asynchronous
- The non-async method for subclass return a ValueTask report AvoidAsyncSuffix
- New rule proposal: Called methods that are not marked async but return a task should be awaited HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from asyncusageanalyzers.