JustDummies

Just dummies — but seriously powerful ones.

Documentation sections

JD008: ArbitraryValueInTheoryData

PropertyValue
CategoryReproducibility (JustDummies.Reproducibility)
Severity🟠 Warning
Enabled by defaultYes

xUnit evaluates a theory’s data provider at discovery, before any test case runs. A value drawn there is therefore drawn once for the whole run, outside every seed scope — Any.Reproducibly and [Reproducible] alike.

Three defects ride on that one shape, and all three are silent:

  • every case of the theory receives the same value, so a theory that reads as if it enumerated arbitrary cases enumerates a constant;
  • the value is replayable from no reported seed, because no seed was pinned when it was drawn;
  • the draw happens even for cases that are filtered out, and its position in the sequence shifts when cases are added or removed.

Draw in the test body, or let the provider yield the generator and materialize it inside the test.

Noncompliant

public static TheoryData<string> Cases => new() {
    Any.String().NonEmpty().Generate(),      // JD008: drawn at discovery, shared by every case
};

[Theory]
[MemberData(nameof(Cases))]
public void It_is_accepted(string reference) { /* ... */ }

Compliant

public static TheoryData<IAny<string>> Cases => new() {
    Any.String().NonEmpty(),                 // the recipe travels, not the value
};

[Theory, Reproducible]
[MemberData(nameof(Cases))]
public void It_is_accepted(IAny<string> reference) {
    string value = reference.Generate();     // drawn per case, inside the pinned scope
}

What it recognises as a provider

A member named by a [MemberData] in the same type; a member returning TheoryData or TheoryData<...>; a member returning a sequence of object[]; and a type implementing that sequence, which is the [ClassData] shape.

What it does not flag

  • A provider that yields generators rather than values — the compliant shape above.
  • A draw in an ordinary test body, which is the point of the rule.
  • A draw from an isolated Any.WithSeed(...) context, or a generator reached through a local or field rather than written inline from Any.

Read the source, or correct it there opens in a new tab· Mirrored from lib-v1.0.0-preview.6