Skip to content

Burla 🎭

Burla logo

Mocking without the nonsense

Burla ("prank" in Italian) is a lightweight, LLM-friendly mocking library for .NET.
It is built for explicit tests, strict defaults, and migrations that do not turn into archaeology.
Start with one awkward test, use the migration guides when the shape feels right, and keep the library surface focused for humans and AI tools alike.

  • Clean API


    Blends the best of Moq's discoverability with NSubstitute's concise matchers. Mock.Of<T>() + Arg.Any<T>() + Setup(...) — straightforward. Works across interfaces, abstract classes, and concrete classes with virtual members.

  • Async-first


    First-class IAsyncEnumerable, Task, and ValueTask support.
    No helper methods needed.

  • Strict by default


    Unconfigured calls throw immediately — no silent bugs.
    Opt in to loose mode when you need it.

  • LLM-friendly


    Setup, argument matching, and verification follow consistent patterns that AI assistants can generate reliably. More of the prompt stays available for the test and production code instead of mock-library quirks.
    Includes a migration prompt for automated conversion.

Quick comparison

Feature Moq NSubstitute Burla
IAsyncEnumerable Helper methods needed Helper methods needed First-class
Ref/Out parameters Verbose delegates Limited support Clean syntax
Strict mode Opt-in ❌ Not available Default
Verification Library-specific API Library-specific API Standard assertions
Arg matchers It.IsAny<T>() Arg.Any<T>() Arg.Any<T>()

Quick start

using Burla;

// Create a strict mock (default)
var mock = Mock.Of<ICalculator>();

// Setup behavior
mock.Setup(x => x.Add(Arg.Any<int>(), Arg.Any<int>())).Returns(42);

// Use it
var result = mock.Instance.Add(1, 2); // returns 42

// Verify using standard xUnit assertions
var calls = mock.CallsTo(x => x.Add(1, 2));
Assert.Single(calls);

Burla-native docs teach verification through CallsTo(...) + standard assertions. Verify(..., Times...) is still available, mainly for low-diff Moq migrations and for VerifyNoOtherCalls().

Burla-native docs use .Instance as the default spelling for the runtime double. If you only need the runtime value, Mock.Create<T>() and Mock.CreateLoose<T>() return it directly; .Object remains available as a Moq compatibility alias.

Install

dotnet add package Burla

Use Burla.Core instead if you want the runtime package without IDE analyzers and code fixes. Burla is the meta-package (Burla.Core + Burla.Analyzers), while Burla.Analyzers is also available directly if you only want the IDE suggestions/code fixes package.

The BURLA01x compatibility analyzer rules default to info. If you want a quieter Moq migration, lower BURLA010, BURLA011, and BURLA012 to silent or none in .editorconfig.

Native API at a glance

  • Mock.Of<T>() / Mock.OfLoose<T>() create mock wrappers; Mock.Create<T>() / Mock.CreateLoose<T>() return the runtime value directly
  • mock.Instance is the native runtime property
  • Setup(...) / SetupSet(...) configure behavior; Arg.* supplies matchers
  • CallsTo(...) + standard assertions is the default verification style, with Verify(..., Times...) and VerifyNoOtherCalls() available when they help
  • Mock.Sequence() / .InSequence(...) handle ordered verification
  • SetsByRefParameter(...) configures ref / out writeback
  • mock.Event(name).Emit(...) emits events
  • mock.Reset() clears mutable state without recreating the runtime instance
  • .Object, It.*, and SetupGet(...) remain available as thin migration aliases, with analyzers BURLA010, BURLA011, BURLA012, and BURLA020

Next steps

What Burla 1.0 covers

Burla 1.0 covers the mocking workflows most teams need in day-to-day test suites, with a focused API that stays easy to learn, easy to read in reviews, and practical to adopt in existing codebases.

It focuses on the patterns most teams hit every day. One notable advanced case still out of scope for 1.0 is protected-member setup.

License

MIT — free forever. No pranks here. 🤝