diff --git a/Benchmarks/Mockolate.Benchmarks/CallbackBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CallbackBenchmarks.cs
index 83b401ef..ef1537b2 100644
--- a/Benchmarks/Mockolate.Benchmarks/CallbackBenchmarks.cs
+++ b/Benchmarks/Mockolate.Benchmarks/CallbackBenchmarks.cs
@@ -31,81 +31,81 @@ public int Callback_Mockolate()
}
///
- ///
+ ///
///
[Benchmark]
- public int Callback_Moq()
+ public int Callback_Imposter()
{
int count = 0;
- Moq.Mock mock = new();
- mock.Setup(x => x.MyFunc(Moq.It.IsAny())).Callback(() => count++);
+ IMyCallbackInterfaceImposter imposter = IMyCallbackInterface.Imposter();
+ imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Callback(_ => count++);
- IMyCallbackInterface instance = mock.Object;
+ IMyCallbackInterface instance = imposter.Instance();
instance.MyFunc(1);
instance.MyFunc(2);
return count;
}
///
- ///
+ ///
///
[Benchmark]
- public int Callback_NSubstitute()
+ public int Callback_TUnitMocks()
{
int count = 0;
- IMyCallbackInterface mock = Substitute.For();
- mock.When(x => x.MyFunc(Arg.Any())).Do(_ => count++);
+ Mock mock = TUnit.Mocks.Mock.Of();
+ mock.MyFunc(Any())
+ .Callback(() => count++);
- mock.MyFunc(1);
- mock.MyFunc(2);
+ IMyCallbackInterface svc = mock.Object;
+ svc.MyFunc(1);
+ svc.MyFunc(2);
return count;
}
///
- ///
+ ///
///
[Benchmark]
- public int Callback_FakeItEasy()
+ public int Callback_Moq()
{
int count = 0;
- IMyCallbackInterface mock = A.Fake();
- A.CallTo(() => mock.MyFunc(A.Ignored)).Invokes(() => count++);
+ Moq.Mock mock = new();
+ mock.Setup(x => x.MyFunc(Moq.It.IsAny())).Callback(() => count++);
- mock.MyFunc(1);
- mock.MyFunc(2);
+ IMyCallbackInterface instance = mock.Object;
+ instance.MyFunc(1);
+ instance.MyFunc(2);
return count;
}
///
- ///
+ ///
///
[Benchmark]
- public int Callback_Imposter()
+ public int Callback_NSubstitute()
{
int count = 0;
- IMyCallbackInterfaceImposter imposter = IMyCallbackInterface.Imposter();
- imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Callback(_ => count++);
+ IMyCallbackInterface mock = Substitute.For();
+ mock.When(x => x.MyFunc(Arg.Any())).Do(_ => count++);
- IMyCallbackInterface instance = imposter.Instance();
- instance.MyFunc(1);
- instance.MyFunc(2);
+ mock.MyFunc(1);
+ mock.MyFunc(2);
return count;
}
///
- ///
+ ///
///
[Benchmark]
- public int Callback_TUnitMocks()
+ public int Callback_FakeItEasy()
{
int count = 0;
- Mock mock = TUnit.Mocks.Mock.Of();
- mock.MyFunc(Any())
- .Callback(() => count++);
+ IMyCallbackInterface mock = A.Fake();
+ A.CallTo(() => mock.MyFunc(A.Ignored)).Invokes(() => count++);
- IMyCallbackInterface svc = mock.Object;
- svc.MyFunc(1);
- svc.MyFunc(2);
+ mock.MyFunc(1);
+ mock.MyFunc(2);
return count;
}
diff --git a/Benchmarks/Mockolate.Benchmarks/CompleteEventBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CompleteEventBenchmarks.cs
index e0850d9e..5373cb70 100644
--- a/Benchmarks/Mockolate.Benchmarks/CompleteEventBenchmarks.cs
+++ b/Benchmarks/Mockolate.Benchmarks/CompleteEventBenchmarks.cs
@@ -5,6 +5,7 @@
using Mockolate.Verify;
using NSubstitute;
using Arg = NSubstitute.Arg;
+using Raise = NSubstitute.Raise;
using Times = Moq.Times;
[assembly: GenerateImposter(typeof(CompleteEventBenchmarks.IMyEventInterface))]
@@ -32,6 +33,36 @@ public void Event_Mockolate()
sut.Mock.Verify.SomeEvent.Subscribed().Once();
}
+ ///
+ ///
+ ///
+ [Benchmark]
+ public void Event_Imposter()
+ {
+ IMyEventInterfaceImposter imposter = IMyEventInterface.Imposter();
+ EventHandler handler = (_, _) => { };
+
+ imposter.Instance().SomeEvent += handler;
+ imposter.SomeEvent.Raise(null!, EventArgs.Empty);
+
+ imposter.SomeEvent.Subscribed(handler, Count.Once());
+ }
+
+ ///
+ ///
+ ///
+ [Benchmark]
+ public void Event_TUnitMocks()
+ {
+ Mock mock = TUnit.Mocks.Mock.Of();
+ EventHandler handler = (_, _) => { };
+
+ mock.Object.SomeEvent += handler;
+ mock.RaiseSomeEvent(EventArgs.Empty);
+
+ _ = mock.Events.SomeEvent.SubscriberCount;
+ }
+
///
///
///
@@ -58,7 +89,7 @@ public void Event_NSubstitute()
EventHandler handler = (_, _) => { };
mock.SomeEvent += handler;
- mock.SomeEvent += NSubstitute.Raise.EventWith(null, EventArgs.Empty);
+ mock.SomeEvent += Raise.EventWith(null, EventArgs.Empty);
mock.Received(1).SomeEvent += Arg.Any();
}
@@ -81,36 +112,6 @@ public void Event_FakeItEasy()
.MustHaveHappened(2, FakeItEasy.Times.Exactly);
}
- ///
- ///
- ///
- [Benchmark]
- public void Event_Imposter()
- {
- IMyEventInterfaceImposter imposter = IMyEventInterface.Imposter();
- EventHandler handler = (_, _) => { };
-
- imposter.Instance().SomeEvent += handler;
- imposter.SomeEvent.Raise(null!, EventArgs.Empty);
-
- imposter.SomeEvent.Subscribed(handler, Count.Once());
- }
-
- ///
- ///
- ///
- [Benchmark]
- public void Event_TUnitMocks()
- {
- Mock mock = TUnit.Mocks.Mock.Of();
- EventHandler handler = (_, _) => { };
-
- mock.Object.SomeEvent += handler;
- mock.RaiseSomeEvent(EventArgs.Empty);
-
- _ = mock.Events.SomeEvent.SubscriberCount;
- }
-
public interface IMyEventInterface
{
event EventHandler? SomeEvent;
diff --git a/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs
index d9c18999..2fc044e5 100644
--- a/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs
+++ b/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs
@@ -17,8 +17,7 @@ namespace Mockolate.Benchmarks;
///
public class CompleteIndexerBenchmarks : BenchmarksBase
{
- [Params(1, 10)]
- public int N { get; set; }
+ [Params(1, 10)] public int N { get; set; }
///
///
@@ -39,6 +38,46 @@ public void Indexer_Mockolate()
sut.Mock.Verify[It.IsAny()].Set(It.IsAny()).Exactly(N);
}
+ ///
+ ///
+ ///
+ [Benchmark]
+ public void Indexer_Imposter()
+ {
+ IMyIndexerInterfaceImposter imposter = IMyIndexerInterface.Imposter();
+ imposter[Imposter.Abstractions.Arg.Any()].Getter().Returns("foo");
+ IMyIndexerInterface sut = imposter.Instance();
+
+ for (int i = 0; i < N; i++)
+ {
+ _ = sut[42];
+ sut[42] = "bar";
+ }
+
+ imposter[Imposter.Abstractions.Arg.Any()].Getter().Called(Count.Exactly(N));
+ imposter[Imposter.Abstractions.Arg.Any()].Setter().Called(Count.Exactly(N));
+ }
+
+ /* Indexers not supported on TUnit.Mocks
+ ///
+ ///
+ ///
+ [Benchmark]
+ public void Indexer_TUnitMocks()
+ {
+ TUnit.Mocks.Mock mock = TUnit.Mocks.Mock.Of();
+ mock[Any()].Returns("foo");
+
+ for (int i = 0; i < N; i++)
+ {
+ _ = mock.Object[42];
+ mock.Object[42] = "bar";
+ }
+
+ mock[Any()].WasCalled(TUnit.Mocks.Times.Exactly(N));
+ }
+ */
+
///
///
///
@@ -97,46 +136,6 @@ public void Indexer_FakeItEasy()
A.CallToSet(() => mock[A.Ignored]).MustHaveHappened(N, FakeItEasy.Times.Exactly);
}
- ///
- ///
- ///
- [Benchmark]
- public void Indexer_Imposter()
- {
- IMyIndexerInterfaceImposter imposter = IMyIndexerInterface.Imposter();
- imposter[Imposter.Abstractions.Arg.Any()].Getter().Returns("foo");
- IMyIndexerInterface sut = imposter.Instance();
-
- for (int i = 0; i < N; i++)
- {
- _ = sut[42];
- sut[42] = "bar";
- }
-
- imposter[Imposter.Abstractions.Arg.Any()].Getter().Called(Count.Exactly(N));
- imposter[Imposter.Abstractions.Arg.Any()].Setter().Called(Count.Exactly(N));
- }
-
- /* Indexers not supported on TUnit.Mocks
- ///
- ///
- ///
- [Benchmark]
- public void Indexer_TUnitMocks()
- {
- TUnit.Mocks.Mock mock = TUnit.Mocks.Mock.Of();
- mock[Any()].Returns("foo");
-
- for (int i = 0; i < N; i++)
- {
- _ = mock.Object[42];
- mock.Object[42] = "bar";
- }
-
- mock[Any()].WasCalled(TUnit.Mocks.Times.Exactly(N));
- }
- */
-
public interface IMyIndexerInterface
{
string this[int index] { get; set; }
diff --git a/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs
index 1ec7b87d..a25cf424 100644
--- a/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs
+++ b/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs
@@ -17,8 +17,7 @@ namespace Mockolate.Benchmarks;
///
public class CompleteMethodBenchmarks : BenchmarksBase
{
- [Params(1, 10)]
- public int N { get; set; }
+ [Params(1, 10)] public int N { get; set; }
///
///
@@ -38,91 +37,91 @@ public void Method_Mockolate()
}
///
- ///
+ ///
///
[Benchmark]
- public void Method_Moq()
+ public void Method_Imposter()
{
- Moq.Mock mock = new();
- mock.Setup(x => x.MyFunc(Moq.It.IsAny())).Returns(true);
- IMyMethodInterface sut = mock.Object;
+ IMyMethodInterfaceImposter imposter = IMyMethodInterface.Imposter();
+ imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Returns(true);
+ IMyMethodInterface sut = imposter.Instance();
for (int i = 0; i < N; i++)
{
sut.MyFunc(42);
}
- mock.Verify(x => x.MyFunc(Moq.It.IsAny()), Times.Exactly(N));
+ imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Called(Count.Exactly(N));
}
///
- ///
+ ///
///
[Benchmark]
- public void Method_NSubstitute()
+ public void Method_TUnitMocks()
{
- IMyMethodInterface mock = Substitute.For();
- mock.MyFunc(Arg.Any()).Returns(true);
+ Mock mock = TUnit.Mocks.Mock.Of();
+ mock.MyFunc(Any()).Returns(true);
+ IMyMethodInterface sut = mock.Object;
for (int i = 0; i < N; i++)
{
- mock.MyFunc(42);
+ sut.MyFunc(42);
}
- mock.Received(N).MyFunc(Arg.Any());
+ mock.MyFunc(Any()).WasCalled(TUnit.Mocks.Times.Exactly(N));
}
///
- ///
+ ///
///
[Benchmark]
- public void Method_FakeItEasy()
+ public void Method_Moq()
{
- IMyMethodInterface mock = A.Fake();
- A.CallTo(() => mock.MyFunc(A.Ignored)).Returns(true);
+ Moq.Mock mock = new();
+ mock.Setup(x => x.MyFunc(Moq.It.IsAny())).Returns(true);
+ IMyMethodInterface sut = mock.Object;
for (int i = 0; i < N; i++)
{
- mock.MyFunc(42);
+ sut.MyFunc(42);
}
- A.CallTo(() => mock.MyFunc(A.Ignored)).MustHaveHappened(N, FakeItEasy.Times.Exactly);
+ mock.Verify(x => x.MyFunc(Moq.It.IsAny()), Times.Exactly(N));
}
///
- ///
+ ///
///
[Benchmark]
- public void Method_Imposter()
+ public void Method_NSubstitute()
{
- IMyMethodInterfaceImposter imposter = IMyMethodInterface.Imposter();
- imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Returns(true);
- IMyMethodInterface sut = imposter.Instance();
+ IMyMethodInterface mock = Substitute.For();
+ mock.MyFunc(Arg.Any()).Returns(true);
for (int i = 0; i < N; i++)
{
- sut.MyFunc(42);
+ mock.MyFunc(42);
}
- imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Called(Count.Exactly(N));
+ mock.Received(N).MyFunc(Arg.Any());
}
///
- ///
+ ///
///
[Benchmark]
- public void Method_TUnitMocks()
+ public void Method_FakeItEasy()
{
- Mock mock = TUnit.Mocks.Mock.Of();
- mock.MyFunc(Any()).Returns(true);
- IMyMethodInterface sut = mock.Object;
+ IMyMethodInterface mock = A.Fake();
+ A.CallTo(() => mock.MyFunc(A.Ignored)).Returns(true);
for (int i = 0; i < N; i++)
{
- sut.MyFunc(42);
+ mock.MyFunc(42);
}
- mock.MyFunc(Any()).WasCalled(TUnit.Mocks.Times.Exactly(N));
+ A.CallTo(() => mock.MyFunc(A.Ignored)).MustHaveHappened(N, FakeItEasy.Times.Exactly);
}
public interface IMyMethodInterface
diff --git a/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs
index 2799c1ba..673d9ad6 100644
--- a/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs
+++ b/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs
@@ -4,6 +4,7 @@
using Mockolate.Benchmarks;
using Mockolate.Verify;
using NSubstitute;
+using Arg = NSubstitute.Arg;
using Times = Moq.Times;
[assembly: GenerateImposter(typeof(CompletePropertyBenchmarks.IMyPropertyInterface))]
@@ -16,8 +17,7 @@ namespace Mockolate.Benchmarks;
///
public class CompletePropertyBenchmarks : BenchmarksBase
{
- [Params(1, 10)]
- public int N { get; set; }
+ [Params(1, 10)] public int N { get; set; }
///
///
@@ -39,14 +39,14 @@ public void Property_Mockolate()
}
///
- ///
+ ///
///
[Benchmark]
- public void Property_Moq()
+ public void Property_Imposter()
{
- Moq.Mock mock = new();
- mock.SetupGet(x => x.Counter).Returns(42);
- IMyPropertyInterface sut = mock.Object;
+ IMyPropertyInterfaceImposter imposter = IMyPropertyInterface.Imposter();
+ imposter.Counter.Getter().Returns(42);
+ IMyPropertyInterface sut = imposter.Instance();
for (int i = 0; i < N; i++)
{
@@ -54,86 +54,86 @@ public void Property_Moq()
sut.Counter = i;
}
- mock.VerifyGet(x => x.Counter, Times.Exactly(N));
- mock.VerifySet(x => x.Counter = Moq.It.IsAny(), Times.Exactly(N));
+ imposter.Counter.Getter().Called(Count.Exactly(N));
+ imposter.Counter.Setter(Imposter.Abstractions.Arg.Any()).Called(Count.Exactly(N));
}
///
- ///
+ ///
///
[Benchmark]
- public void Property_NSubstitute()
+ public void Property_TUnitMocks()
{
- IMyPropertyInterface mock = Substitute.For();
+ Mock mock = TUnit.Mocks.Mock.Of();
mock.Counter.Returns(42);
+ IMyPropertyInterface sut = mock.Object;
for (int i = 0; i < N; i++)
{
- _ = mock.Counter;
- mock.Counter = i;
+ _ = sut.Counter;
+ sut.Counter = i;
}
- _ = mock.Received(N).Counter;
- mock.Received(N).Counter = NSubstitute.Arg.Any();
+ mock.Counter.WasCalled(TUnit.Mocks.Times.Exactly(N));
+ mock.Counter.Setter.WasCalled(TUnit.Mocks.Times.Exactly(N));
}
///
- ///
+ ///
///
[Benchmark]
- public void Property_FakeItEasy()
+ public void Property_Moq()
{
- IMyPropertyInterface mock = A.Fake();
- A.CallTo(() => mock.Counter).Returns(42);
+ Moq.Mock mock = new();
+ mock.SetupGet(x => x.Counter).Returns(42);
+ IMyPropertyInterface sut = mock.Object;
for (int i = 0; i < N; i++)
{
- _ = mock.Counter;
- mock.Counter = i;
+ _ = sut.Counter;
+ sut.Counter = i;
}
- A.CallTo(() => mock.Counter).MustHaveHappened(N, FakeItEasy.Times.Exactly);
- A.CallToSet(() => mock.Counter).MustHaveHappened(N, FakeItEasy.Times.Exactly);
+ mock.VerifyGet(x => x.Counter, Times.Exactly(N));
+ mock.VerifySet(x => x.Counter = Moq.It.IsAny(), Times.Exactly(N));
}
///
- ///
+ ///
///
[Benchmark]
- public void Property_Imposter()
+ public void Property_NSubstitute()
{
- IMyPropertyInterfaceImposter imposter = IMyPropertyInterface.Imposter();
- imposter.Counter.Getter().Returns(42);
- IMyPropertyInterface sut = imposter.Instance();
+ IMyPropertyInterface mock = Substitute.For();
+ mock.Counter.Returns(42);
for (int i = 0; i < N; i++)
{
- _ = sut.Counter;
- sut.Counter = i;
+ _ = mock.Counter;
+ mock.Counter = i;
}
- imposter.Counter.Getter().Called(Count.Exactly(N));
- imposter.Counter.Setter(Imposter.Abstractions.Arg.Any()).Called(Count.Exactly(N));
+ _ = mock.Received(N).Counter;
+ mock.Received(N).Counter = Arg.Any();
}
///
- ///
+ ///
///
[Benchmark]
- public void Property_TUnitMocks()
+ public void Property_FakeItEasy()
{
- Mock mock = TUnit.Mocks.Mock.Of();
- mock.Counter.Returns(42);
- IMyPropertyInterface sut = mock.Object;
+ IMyPropertyInterface mock = A.Fake();
+ A.CallTo(() => mock.Counter).Returns(42);
for (int i = 0; i < N; i++)
{
- _ = sut.Counter;
- sut.Counter = i;
+ _ = mock.Counter;
+ mock.Counter = i;
}
- mock.Counter.WasCalled(TUnit.Mocks.Times.Exactly(N));
- mock.Counter.Setter.WasCalled(TUnit.Mocks.Times.Exactly(N));
+ A.CallTo(() => mock.Counter).MustHaveHappened(N, FakeItEasy.Times.Exactly);
+ A.CallToSet(() => mock.Counter).MustHaveHappened(N, FakeItEasy.Times.Exactly);
}
public interface IMyPropertyInterface
@@ -141,4 +141,4 @@ public interface IMyPropertyInterface
int Counter { get; set; }
}
}
-#pragma warning restore CA1822 // Mark members as static
\ No newline at end of file
+#pragma warning restore CA1822 // Mark members as static
diff --git a/Docs/pages/00-index.md b/Docs/pages/00-index.md
index 1bdc7a9b..0fefd34e 100644
--- a/Docs/pages/00-index.md
+++ b/Docs/pages/00-index.md
@@ -15,12 +15,12 @@ It enables fast, compile-time validated mocking with .NET Standard 2.0, .NET 8,
## Why Mockolate
-| | Reflection-based mocks (Moq, NSubstitute, …) | Mockolate |
-|---|---|---|
-| AOT / trimming | not supported | supported |
-| Validation | runtime exceptions | analyzers + compile errors |
-| Setup API | `Expression>` trees | regular method calls |
-| Hot path | dynamic-proxy dispatch | direct dispatch |
+| | Reflection-based mocks (Moq, NSubstitute, …) | Mockolate |
+|----------------|----------------------------------------------|----------------------------|
+| AOT / trimming | not supported | supported |
+| Validation | runtime exceptions | analyzers + compile errors |
+| Setup API | `Expression>` trees | regular method calls |
+| Hot path | dynamic-proxy dispatch | direct dispatch |
For side-by-side setup, usage, and verification syntax against Moq, NSubstitute, and FakeItEasy, see the [full code comparison](08-comparison.md).
diff --git a/Docs/pages/01-create-mocks.md b/Docs/pages/01-create-mocks.md
index b7524fa7..7dfdbc32 100644
--- a/Docs/pages/01-create-mocks.md
+++ b/Docs/pages/01-create-mocks.md
@@ -28,14 +28,14 @@ MyChocolateDispenser classMock = MyChocolateDispenser.CreateMock(behavior, "Dark
**`MockBehavior` options**
-| Option | Default | Purpose |
-|---|---|---|
-| `SkipBaseClass` | `false` | When `true`, the mock does not call any base class implementations. Otherwise, the base class implementation is used as the default value when no explicit setup matches. |
-| `ThrowWhenNotSetup` | `false` | When `true`, the mock throws when no matching setup is found. Otherwise, it returns a default value (see `DefaultValue` below). |
-| `SkipInteractionRecording` | `false` | When `true`, interactions are not recorded - setups, returns, callbacks, and base-class delegation still work, but `.Verify.X()` throws a `MockException`. Useful in performance-sensitive scenarios. |
-| `DefaultValue` | sensible defaults | Customizes how default values are generated for unset methods and properties (see below). |
-| `Initialize(...)` | - | Automatically applies the given setups to all mocks of type `T` when they are created. |
-| `UseConstructorParametersFor(...)` | - | Configures default constructor parameters for mocks of type `T`, unless explicit parameters are supplied to `CreateMock([…])`. The `Func