From 17dca32f8b09a726f068110526a6fa4829641763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Valentin=20Breu=C3=9F?= Date: Sat, 18 Apr 2026 06:21:26 +0200 Subject: [PATCH] refactor: parametrize benchmark iterations for indexers, methods, and properties --- .idea/.idea.Mockolate/.idea/.name | 1 + .../CompleteIndexerBenchmarks.cs | 47 ++++++++++++++----- .../CompleteMethodBenchmarks.cs | 47 ++++++++++++++----- .../CompletePropertyBenchmarks.cs | 47 ++++++++++++++----- 4 files changed, 103 insertions(+), 39 deletions(-) create mode 100644 .idea/.idea.Mockolate/.idea/.name diff --git a/.idea/.idea.Mockolate/.idea/.name b/.idea/.idea.Mockolate/.idea/.name new file mode 100644 index 00000000..0158a9ea --- /dev/null +++ b/.idea/.idea.Mockolate/.idea/.name @@ -0,0 +1 @@ +Mockolate \ No newline at end of file diff --git a/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs index d1e17c97..3c227d3b 100644 --- a/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs +++ b/Benchmarks/Mockolate.Benchmarks/CompleteIndexerBenchmarks.cs @@ -13,10 +13,13 @@ namespace Mockolate.Benchmarks; #pragma warning disable CA1822 // Mark members as static /// /// In this benchmark we check the case of an interface mock with an indexer, setup the indexer and verify -/// the getter was called once. +/// the getter was called exactly times. /// public class CompleteIndexerBenchmarks : BenchmarksBase { + [Params(1, 10)] + public int InvocationCount { get; set; } + /// /// /// @@ -26,9 +29,12 @@ public void Indexer_Mockolate() IMyIndexerInterface sut = IMyIndexerInterface.CreateMock(); sut.Mock.Setup[It.IsAny()].Returns("foo"); - _ = sut[42]; + for (int i = 0; i < InvocationCount; i++) + { + _ = sut[42]; + } - sut.Mock.Verify[It.IsAny()].Got().Once(); + sut.Mock.Verify[It.IsAny()].Got().Exactly(InvocationCount); } /// @@ -40,9 +46,12 @@ public void Indexer_Moq() Moq.Mock mock = new(); mock.Setup(x => x[Moq.It.IsAny()]).Returns("foo"); - _ = mock.Object[42]; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock.Object[42]; + } - mock.Verify(x => x[Moq.It.IsAny()], Times.Once()); + mock.Verify(x => x[Moq.It.IsAny()], Times.Exactly(InvocationCount)); } /// @@ -54,9 +63,12 @@ public void Indexer_NSubstitute() IMyIndexerInterface mock = Substitute.For(); mock[Arg.Any()].Returns("foo"); - _ = mock[42]; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock[42]; + } - _ = mock.Received(1)[Arg.Any()]; + _ = mock.Received(InvocationCount)[Arg.Any()]; } /// @@ -68,9 +80,12 @@ public void Indexer_FakeItEasy() IMyIndexerInterface mock = A.Fake(); A.CallTo(() => mock[A.Ignored]).Returns("foo"); - _ = mock[42]; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock[42]; + } - A.CallTo(() => mock[A.Ignored]).MustHaveHappened(1, FakeItEasy.Times.Exactly); + A.CallTo(() => mock[A.Ignored]).MustHaveHappened(InvocationCount, FakeItEasy.Times.Exactly); } /// @@ -82,9 +97,12 @@ public void Indexer_Imposter() IMyIndexerInterfaceImposter imposter = IMyIndexerInterface.Imposter(); imposter[Imposter.Abstractions.Arg.Any()].Getter().Returns("foo"); - _ = imposter.Instance()[42]; + for (int i = 0; i < InvocationCount; i++) + { + _ = imposter.Instance()[42]; + } - imposter[Imposter.Abstractions.Arg.Any()].Getter().Called(Count.Once()); + imposter[Imposter.Abstractions.Arg.Any()].Getter().Called(Count.Exactly(InvocationCount)); } /* Indexers not supported on TUnit.Mocks @@ -97,9 +115,12 @@ public void Indexer_TUnitMocks() TUnit.Mocks.Mock mock = TUnit.Mocks.Mock.Of(); mock[Any()].Returns("foo"); - _ = mock.Object[42]; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock.Object[42]; + } - mock[Any()].WasCalled(); + mock[Any()].WasCalled(TUnit.Mocks.Times.Exactly(InvocationCount)); } */ diff --git a/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs index a1296718..454768c7 100644 --- a/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs +++ b/Benchmarks/Mockolate.Benchmarks/CompleteMethodBenchmarks.cs @@ -13,10 +13,13 @@ namespace Mockolate.Benchmarks; #pragma warning disable CA1822 // Mark members as static /// /// In this benchmark we check the simple case of an interface mock, setup a single method that gets called and -/// verified to be called once. +/// verified to be called exactly times. /// public class CompleteMethodBenchmarks : BenchmarksBase { + [Params(1, 10)] + public int InvocationCount { get; set; } + /// /// /// @@ -26,9 +29,12 @@ public void Method_Mockolate() IMyMethodInterface sut = IMyMethodInterface.CreateMock(); sut.Mock.Setup.MyFunc(It.IsAny()).Returns(true); - sut.MyFunc(42); + for (int i = 0; i < InvocationCount; i++) + { + sut.MyFunc(42); + } - sut.Mock.Verify.MyFunc(It.IsAny()).Once(); + sut.Mock.Verify.MyFunc(It.IsAny()).Exactly(InvocationCount); } /// @@ -40,9 +46,12 @@ public void Method_Moq() Moq.Mock mock = new(); mock.Setup(x => x.MyFunc(Moq.It.IsAny())).Returns(true); - mock.Object.MyFunc(42); + for (int i = 0; i < InvocationCount; i++) + { + mock.Object.MyFunc(42); + } - mock.Verify(x => x.MyFunc(Moq.It.IsAny()), Times.Once()); + mock.Verify(x => x.MyFunc(Moq.It.IsAny()), Times.Exactly(InvocationCount)); } /// @@ -54,9 +63,12 @@ public void Method_NSubstitute() IMyMethodInterface mock = Substitute.For(); mock.MyFunc(Arg.Any()).Returns(true); - mock.MyFunc(42); + for (int i = 0; i < InvocationCount; i++) + { + mock.MyFunc(42); + } - mock.Received(1).MyFunc(Arg.Any()); + mock.Received(InvocationCount).MyFunc(Arg.Any()); } /// @@ -68,9 +80,12 @@ public void Method_FakeItEasy() IMyMethodInterface mock = A.Fake(); A.CallTo(() => mock.MyFunc(A.Ignored)).Returns(true); - mock.MyFunc(42); + for (int i = 0; i < InvocationCount; i++) + { + mock.MyFunc(42); + } - A.CallTo(() => mock.MyFunc(A.Ignored)).MustHaveHappened(1, FakeItEasy.Times.Exactly); + A.CallTo(() => mock.MyFunc(A.Ignored)).MustHaveHappened(InvocationCount, FakeItEasy.Times.Exactly); } /// @@ -82,9 +97,12 @@ public void Method_Imposter() IMyMethodInterfaceImposter imposter = IMyMethodInterface.Imposter(); imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Returns(true); - imposter.Instance().MyFunc(42); + for (int i = 0; i < InvocationCount; i++) + { + imposter.Instance().MyFunc(42); + } - imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Called(Count.Once()); + imposter.MyFunc(Imposter.Abstractions.Arg.Any()).Called(Count.Exactly(InvocationCount)); } /// @@ -96,9 +114,12 @@ public void Method_TUnitMocks() Mock mock = TUnit.Mocks.Mock.Of(); mock.MyFunc(Any()).Returns(true); - mock.Object.MyFunc(42); + for (int i = 0; i < InvocationCount; i++) + { + mock.Object.MyFunc(42); + } - mock.MyFunc(Any()).WasCalled(); + mock.MyFunc(Any()).WasCalled(TUnit.Mocks.Times.Exactly(InvocationCount)); } public interface IMyMethodInterface diff --git a/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs b/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs index d6ad7d0c..15ea2fb5 100644 --- a/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs +++ b/Benchmarks/Mockolate.Benchmarks/CompletePropertyBenchmarks.cs @@ -12,10 +12,13 @@ namespace Mockolate.Benchmarks; #pragma warning disable CA1822 // Mark members as static /// /// In this benchmark we check the case of an interface mock with a property, setup the property and verify -/// the getter was called once. +/// the getter was called exactly times. /// public class CompletePropertyBenchmarks : BenchmarksBase { + [Params(1, 10)] + public int InvocationCount { get; set; } + /// /// /// @@ -25,9 +28,12 @@ public void Property_Mockolate() IMyPropertyInterface sut = IMyPropertyInterface.CreateMock(); sut.Mock.Setup.Counter.InitializeWith(42); - _ = sut.Counter; + for (int i = 0; i < InvocationCount; i++) + { + _ = sut.Counter; + } - sut.Mock.Verify.Counter.Got().Once(); + sut.Mock.Verify.Counter.Got().Exactly(InvocationCount); } /// @@ -39,9 +45,12 @@ public void Property_Moq() Moq.Mock mock = new(); mock.SetupGet(x => x.Counter).Returns(42); - _ = mock.Object.Counter; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock.Object.Counter; + } - mock.VerifyGet(x => x.Counter, Times.Once()); + mock.VerifyGet(x => x.Counter, Times.Exactly(InvocationCount)); } /// @@ -53,9 +62,12 @@ public void Property_NSubstitute() IMyPropertyInterface mock = Substitute.For(); mock.Counter.Returns(42); - _ = mock.Counter; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock.Counter; + } - _ = mock.Received(1).Counter; + _ = mock.Received(InvocationCount).Counter; } /// @@ -67,9 +79,12 @@ public void Property_FakeItEasy() IMyPropertyInterface mock = A.Fake(); A.CallTo(() => mock.Counter).Returns(42); - _ = mock.Counter; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock.Counter; + } - A.CallTo(() => mock.Counter).MustHaveHappened(1, FakeItEasy.Times.Exactly); + A.CallTo(() => mock.Counter).MustHaveHappened(InvocationCount, FakeItEasy.Times.Exactly); } /// @@ -81,9 +96,12 @@ public void Property_Imposter() IMyPropertyInterfaceImposter imposter = IMyPropertyInterface.Imposter(); imposter.Counter.Getter().Returns(42); - _ = imposter.Instance().Counter; + for (int i = 0; i < InvocationCount; i++) + { + _ = imposter.Instance().Counter; + } - imposter.Counter.Getter().Called(Count.Once()); + imposter.Counter.Getter().Called(Count.Exactly(InvocationCount)); } /// @@ -95,9 +113,12 @@ public void Property_TUnitMocks() Mock mock = TUnit.Mocks.Mock.Of(); mock.Counter.Returns(42); - _ = mock.Object.Counter; + for (int i = 0; i < InvocationCount; i++) + { + _ = mock.Object.Counter; + } - mock.Counter.WasCalled(); + mock.Counter.WasCalled(TUnit.Mocks.Times.Exactly(InvocationCount)); } public interface IMyPropertyInterface