π Languages:
π¬π§ English (this file) | π«π· FranΓ§ais
| Build | |
| Quality | |
| Security | |
| Package | |
| Project |
A fluent DSL for generating arbitrary yet valid test values: dummies.
Every test is full of values it does not care about.
string reference = "ORD-12345678";
int quantity = 3;A reader cannot tell whether 3 matters or whether 7 would do. Every literal looks equally
load-bearing, so nobody dares change one β and the test only ever covers that one case. A defect
needing a different shape of input is a defect this test can never find.
Say what the value must satisfy, and let the library draw one that does:
string reference = Any.String().StartingWith("ORD-").WithLength(12).Generate();
int quantity = Any.Int32().Between(1, 100).Generate();
Guid id = Any.Guid().NonEmpty().Generate();The test now states its assumptions. Everything else varies between runs, which is what makes it find things.
An Any.* call returns a generator β an immutable recipe β and .Generate() draws a value from
it. A value object with a stricter contract is built by transforming a constrained primitive through
its real factory:
OrderReference orderRef = Any.String()
.StartingWith("ORD-")
.WithLength(12)
.As(OrderReference.Create)
.Generate();The one rule that matters: a constraint states an invariant of the domain, never what the test asserts. Contradictory constraints fail fast, with a message naming both sides.
dotnet add package JustDummiesNo runtime dependency, and the 29 analyzer rules come bundled inside β they start working on your next build.
Random values in tests are only acceptable if a failure can be replayed. Wrap the test body:
Any.Reproducibly(() => {
decimal orderTotal = Any.Decimal().Between(0m, 10_000m).WithScale(2).Generate();
Assert.InRange(Shipping.FeeFor(orderTotal), 0m, 4.90m);
});When it goes red β and only then β the seed that produced the run is reported:
[JustDummies] These arbitrary values were seeded with 1743029518. Reproduce this run with Any.Reproducibly(1743029518, ...).
Copy that number in front of the body. Same test, one argument more, and the exact run comes back β value for value:
Any.Reproducibly(1743029518, () => {
// the same body as above; only the seed was added
});Fix the defect, then delete the seed so the test varies again.
With xUnit v3, [Reproducible] replaces the wrapping entirely β see
the adapter. From 1.0.0-preview.1 a
seed replays across every patch and minor of a major version, enforced by a golden master
(ADR-0049).
Writing an IAny<T> by hand for each of your domain types is the tedious part. dum writes the
first draft:
dotnet tool install --global JustDummies.Cli
dum generate Order reference OrderReference Any.String().NonEmpty().As(OrderReference.Create) factory, guard
customer Customer β TODO
quantity int Any.Int32().Positive() guard
β AnyOrder.cs β 5 of 6 parameters inferred, 1 TODO.
It reads your compilation, tightens what the constructor's own guard clauses tell it
(quantity <= 0 β .Positive()), and emits ordinary code you then own. What it could not infer it
leaves as an identifier that does not exist β so your build names the gap, at the line, instead
of a plausible value being drawn behind your back.
β JustDummies.Cli
β Start with the ten-minute guide
| Documentation index | everything, organised, in English and French |
| Core concepts | recipe versus value, and the golden rule |
| Generator reference | every Any.* factory and its constraints |
| Reproducibility | seeds, scopes and replay |
| Composition | dummies for your own types |
| Analyzer rules | one page per diagnostic |
| Design principles | what it refuses on purpose, and why |
| Package | What it is |
|---|---|
JustDummies |
the library, with its 29 rules bundled in |
JustDummies.Xunit |
the xUnit v3 adapter: [Reproducible] |
JustDummies.DiagnosticCatalog |
the JD001βJD029 rules as compile-checked constants |
JustDummies.Cli |
dum, the scaffolder β a global tool, never a project reference |
The three libraries target netstandard2.0; JustDummies additionally carries a net8.0 asset with
the modern generators (DateOnly, TimeOnly, Int128, UInt128, Half). The supported .NET
Framework floor is 4.7.2 (ADR-0007).
dum is a tool rather than a library: it targets net8.0 and rolls forward, whatever the project it
analyzes targets.
Preview. The public surface is declared in
PublicAPI.Unshipped.txt: nothing about it is promised yet, and a stable release is what will freeze it. The seed contract is the exception β see above. Which versions are on nuget.org is not repeated here, because a copy of that goes stale the day after a release: read the package listing.
Issues and pull requests are welcome. Start with CONTRIBUTING.md for the commit
conventions and the test-bed rules, and SECURITY.md to report a vulnerability.
dotnet build JustDummies.sln -c Release
dotnet test JustDummies.sln -c ReleaseThe repository targets the .NET 10 SDK (pinned in global.json). Maintainer material β architecture
decisions, workflows, specifications β is under
doc/handwritten/for-maintainers/.
This repository was extracted from
Reefact/first-class-errors on 2026-07-31 with
git filter-repo, preserving authors, dates and commit messages. Commit hashes therefore differ
from the source repository, and issue/PR numbers in commit messages dated before the extraction refer
to Reefact/first-class-errors. The full record is in
doc/handwritten/for-maintainers/migration/; the
decision is ADR-0044.
Licensed under Apache 2.0.