| Property | Value |
|---|---|
| Category | Reproducibility (JustDummies.Reproducibility) |
| Severity | 🔴 Error |
| Enabled by default | Yes |
JD001 reports an async lambda passed to Any.Reproducibly. Two neighbouring shapes do the same damage and JD001 does not see either, because it reads the lambda’s own async marker:
- a synchronous lambda whose body produces a task —
Any.Reproducibly(() => sut.SaveAsync(x)). The lambda binds toAction, so the task is created and dropped.CS4014does not fire, because the enclosing lambda is not itselfasync; - an
async voidmethod passed as a method group —Any.Reproducibly(Body). It binds toActionwith no warning, and its post-awaitexception escapes the reproducible scope’stry/catchentirely.
In both cases Any.Reproducibly returns before the body’s assertions run, and their failures never reach the test runner. The test passes green.
Pass the asynchronous body to Any.ReproduciblyAsync(Func<Task>) and await it.
Noncompliant
[Fact]
public void Prices_are_saved() {
Any.Reproducibly(() => _repository.SaveAsync(price)); // JD003: the task is dropped
}
[Fact]
public void Prices_are_saved_too() {
Any.Reproducibly(SaveAsync); // JD003: 'async void' bound to Action
}
private static async void SaveAsync() { /* ... */ }
Compliant
[Fact]
public async Task Prices_are_saved() {
await Any.ReproduciblyAsync(() => _repository.SaveAsync(price));
}
What it does not flag
- A nested lambda or local function inside the body. Its binding and its author’s intent are its own, so a deliberate fire-and-forget there is not this call’s business.
- An
asynclambda — that is JD001’s subject, and reporting both would raise two errors for one mistake. - A body whose calls all return
void.