Thank you for your interest in contributing to Imposter! This guide will help you get started.
- .NET SDK 9.0+
- An editor with Roslyn Source Generator support (VS 2022 17.10+, Rider, or VS Code + C# Dev Kit)
git clone https://github.com/themidnightgospel/Imposter.git
cd Imposter
dotnet build Imposter.slnUse the CI-style script for full verification:
./build-and-test.ps1Or run tests directly:
dotnet test Imposter.slndotnet run -c Release -p benchmarks/Imposter.Benchmarks/Imposter.Benchmarks.csproj| Path | Purpose |
|---|---|
src/Imposter.Abstractions |
Public runtime API (attributes, matchers, verification) |
src/Imposter.CodeGenerator |
Roslyn Incremental Source Generator |
tests/Imposter.Tests |
Behaviour tests (xUnit + Shouldly) |
tests/Imposter.Abstractions.Tests |
Unit tests for abstractions |
tests/Imposter.CodeGenerator.Tests |
Generator-specific compilation tests |
benchmarks/Imposter.Benchmarks |
BenchmarkDotNet suite vs Moq, NSubstitute, FakeItEasy, Rocks |
Open a GitHub issue with:
- A minimal interface definition that triggers the problem
- The compiler error or unexpected behaviour you observe
- Your .NET SDK version and target framework
Open an issue describing the use case and expected API surface. Include code examples where possible.
- Fork the repository and create a branch from
master. - Make your changes following the coding standards below.
- Add or update tests to cover new behaviour.
- Run
./build-and-test.ps1and ensure all tests pass. - Open a PR against
masterwith a clear description of what and why.
- Never use string templates, interpolation, or concatenation to generate code.
- Always use
SyntaxFactoryandSyntaxFactoryHelperto construct syntax trees. - Use builder classes (
ClassDeclarationBuilder,MethodDeclarationBuilder, etc.) over rawSyntaxFactorychains. - Use
WellKnownTypesandNameSetfor type/member names — no hardcoded string literals for generated identifiers.
- Define
readonly structmetadata that describes the generated structure before writing builders. - Builders consume metadata to emit syntax — keep them free of structural decisions.
- Organize under
Features/<Area>/Metadatawith corresponding builders.
- Types:
PascalCase - Interfaces:
Iprefix (IHaveImposterInstance) - Private fields:
_camelCase - Constants:
PascalCase
- Use "impersonate / impersonation" instead of "mock / mocking" in code, comments, and docs.
- Generated types are called "imposters".
- Exception: when comparing to other libraries, "mocking" is acceptable for clarity.
- Framework: xUnit with
[Fact]tests and Shouldly assertions. - Test naming:
Given_<Context>_When_<Action>_Should_<Outcome> - Place behaviour tests under
tests/Imposter.Tests/Features/<FeatureName>/. - Place generator compilation tests under
tests/Imposter.CodeGenerator.Tests/Issues/Issue<N>/for bug reproductions. - Each test class creates a single readonly SUT:
private readonly <Name>Imposter _sut = new <Name>Imposter(); - Call the subject via
_sut.Instance(); configure behaviour on_sut.
- Never edit files ending with
.g.cs— they are generated output. - Make changes in the generator or metadata, then rebuild to regenerate.
- Inspect generated output at
tests/Imposter.Tests/GeneratedFiles/after building.
- Changes are scoped and focused (no unrelated formatting diffs)
- Tests added or updated to cover new behaviour
-
./build-and-test.ps1passes (ordotnet test Imposter.sln) - Release build compiles clean (warnings treated as errors)
- No string-based code generation introduced
- Terminology uses "impersonate/imposter" (not "mock")
- Consumer marks an interface with
[GenerateImposter] - The Roslyn generator discovers the attribute and emits an imposter type (e.g.,
IMyServiceImposter) - The imposter exposes a fluent API for setup (
.Returns(),.Throws(),.Callback()) and verification (.Called()) - Test code calls
imposter.Instance()to get a wired implementation of the target interface
Key entrypoints:
- Attribute:
src/Imposter.Abstractions/GenerateImposterAttribute.cs - Generator:
src/Imposter.CodeGenerator/CodeGenerator/ImposterGenerator.cs - Example test:
tests/Imposter.Tests/Features/MethodImpersonation/ReturnValueSetupTests.cs
By contributing, you agree that your contributions will be licensed under the MIT License.