Introduction
Mokkit is a test-orchestration toolkit for .NET and for Go. It doesn’t replace your test framework, your mocking library, or your DI container — it sits on top of them and gives your tests a shape and a language.
That language is the whole point.
The idea
Section titled “The idea”Good tests describe a scenario. Read one aloud and it should sound like a sentence someone on the team would say:
Given a new client Acme Corporation that’s already in the cache, when we create it, then the API returns Created, the row is in the database, and a
clients.createdevent is published.
BDD tools like Cucumber and SpecFlow chase that readability with a separate language — Gherkin feature files, plus “step bindings” that glue each English phrase to some C# behind the scenes. You get prose, but you pay for it: a second syntax, a runtime binding layer, and steps that can drift out of sync with the code without the compiler noticing.
Mokkit takes the other road. The same scenario, as a Mokkit test:
await Arrange .NewClient(out var client, WithName("Acme Corporation")) .CacheHasClient(client);
var result = await Act(client);
await Inspect .WriteResult(result).Created() .Ensure(result, r => r.ClientId, out var id) .ApiClientMatches(id, name: "Acme Corporation") .DbClientExists(id) .EventPublished("clients.created", id);f.Arrange(). NewClient[Client](WithName("Acme Corporation")). CacheHasClient(f.Of[Client]())
result := f.Act().Create(f.Of[Client]())
f.Inspect(). Created(result). ApiClientMatches(result.ID, "Acme Corporation"). DbClientExists(result.ID). EventPublished("clients.created", result.ID)It reads like the sentence above — but there is no DSL. NewClient, CacheHasClient, Created,
ApiClientMatches, EventPublished are just methods you wrote, in your language: your project’s testing
vocabulary. Because it’s plain code, you get everything the compiler and IDE give you — autocomplete,
go-to-definition, rename-refactoring, and the guarantee that a test that doesn’t make sense won’t
compile.
The shape: Arrange / Act / Inspect
Section titled “The shape: Arrange / Act / Inspect”Every Mokkit test follows the same three-phase story (Arrange-Act-Assert, with the assert phase named Inspect):
- Arrange — set up the world and capture the artifacts later steps refer to.
- Act — perform the one thing under test; it yields a result.
- Inspect — observe the outcome. Inspect only reads; it never changes state.
Each phase is a fluent chain of the verbs you defined. See Arrange / Act / Inspect for the mechanics and Building your test vocabulary for the part that matters most.
One idea, two languages
Section titled “One idea, two languages”Mokkit began in C# and was ported to Go, and the port is a translation rather than a transliteration: the shape, the vocabulary discipline and the composition model carry over, while each side speaks its language natively.
| C# | Go | |
|---|---|---|
| Chains | deferred, run by await |
eager — a verb has already run when it returns |
| Artifacts | out var captures (Captures) |
typed tokens (Tokens) |
| Interaction asserts | mock library’s own, plus Satisfied()-style pull-forward |
same idea, per adapter |
| Failure phases | Inspect wraps Assert.Multiple |
Inspect fails soft natively |
| API reference | DocFX | pkg.go.dev |
Pages on this site teach both: shared concepts show the same example in a C#/Go tab pair (your choice sticks as you navigate), and the few ideas that exist in only one language carry a badge in the sidebar.
Agnostic by design
Section titled “Agnostic by design”Mokkit assumes nothing about the rest of your stack:
- Test framework — xUnit, NUnit, MSTest, TUnit — or Go’s
testing; Mokkit is just calls inside your test functions. - Mocking — first-class adapters for Moq, NSubstitute and FakeItEasy in C#; gomock, mockery/testify and minimock in Go (or bring your own).
- DI container — Microsoft.Extensions.DependencyInjection, Autofac, Castle Windsor in C#; samber/do and uber-go/dig in Go; or the dependency-free Bag container both sides ship for tests that just need to hold a few instances.
The same vocabulary and the same test shape carry from a fast, fully-mocked unit test to an integration test against a real database, up to a black-box end-to-end test that boots your whole system in Docker. The guides walk each of those.
Next steps
Section titled “Next steps”- Why Mokkit? — the honest comparison with BDD/DSL frameworks.
- Installation — the packages and how to pick them.
- Quickstart — a complete test in a few minutes.