feat: add benchmarks for Imposter and Mockolate mocking frameworks#5295
Conversation
8ca4bf2 to
fdd6cca
Compare
There was a problem hiding this comment.
Code Review
Good addition to expand the benchmark coverage to Imposter and Mockolate. The benchmarks cover the full set of scenarios (creation, setup, invocation, callbacks, verification, combined workflow), which is consistent with how the existing frameworks are benchmarked. A few issues worth addressing before merging:
Bug: Inconsistent use of imposter.Instance() in VerificationBenchmarks.cs
In CallbackBenchmarks.cs and CombinedWorkflowBenchmarks.cs, the Imposter benchmarks correctly retrieve the typed interface instance before invoking methods:
var instance = imposter.Instance();
instance.Send("user@test.com", "Hello");But in VerificationBenchmarks.cs (both Imposter_Verify and Imposter_VerifyMultiple), methods are called directly on imposter without calling .Instance():
var calc = imposter; // this is the imposter wrapper, not the interface instance
calc.Add(1, 2); // are these calls actually being recorded?If ICalculatorServiceImposter doesn't implement ICalculatorService, these calls go to a different code path than what's intended — meaning the verify assertions may be vacuously true (verifying 0 calls = 0 expected) rather than validating that real invocations were counted. The benchmarks would be measuring something different from the other frameworks.
Potential issue: Imposter_CreateMock returns the wrapper, not the instance
public object Imposter_CreateMock()
{
var imposter = ICalculatorService.Imposter();
return imposter; // returns the ICalculatorServiceImposter wrapper
}All other frameworks return the actual mock object (the ICalculatorService-implementing instance). The Mockolate version also returns the mock object directly since CreateMock() returns the mock implementing the interface. For a fair comparison, Imposter should probably return imposter.Instance() here as well.
Potential duplicate [assembly: GenerateImposter] attributes
The same type is registered with [assembly: GenerateImposter] in multiple files:
ICalculatorServiceappears inMockCreationBenchmarks.cs,SetupBenchmarks.cs,InvocationBenchmarks.cs, andVerificationBenchmarks.csIUserRepositoryappears inMockCreationBenchmarks.cs,SetupBenchmarks.cs,CombinedWorkflowBenchmarks.cs, andVerificationBenchmarks.cs
If GenerateImposterAttribute has AllowMultiple = true, this compiles but may cause the source generator to emit duplicate code (duplicate class definitions). If it has AllowMultiple = false, this is a compile error. These should be consolidated into a single location (e.g., a dedicated ImposterRegistrations.cs file, similar to how the existing code groups them), with one [assembly: GenerateImposter] per type.
Minor: Mixed indentation in Directory.Packages.props
The Imposter entry uses a tab while Mockolate uses spaces, which is inconsistent with the rest of the file.
Summary
The overall structure is solid and consistent with the existing benchmark patterns. The main concern is the correctness of the Imposter verification benchmarks — if methods are being called on the wrapper instead of the interface instance, those benchmarks don't measure what they appear to measure. Please verify the VerificationBenchmarks Imposter code path produces correct call-count tracking before merging.
7621651 to
c244de4
Compare
There was a problem hiding this comment.
Follow-up Code Review
Comparing against my previous review on the earlier commit — two of the four issues have been addressed:
✅ Fixed: Imposter_CreateMock now returns imposter.Instance()
✅ Fixed: VerificationBenchmarks now correctly calls imposter.Instance() before invoking methods
Still present: Duplicate [assembly: GenerateImposter] attributes
The same types are still declared in multiple files:
ICalculatorService:MockCreationBenchmarks.cs,SetupBenchmarks.cs,InvocationBenchmarks.cs,VerificationBenchmarks.csIUserRepository:MockCreationBenchmarks.cs,SetupBenchmarks.cs,CombinedWorkflowBenchmarks.cs,VerificationBenchmarks.csILogger:CallbackBenchmarks.cs,CombinedWorkflowBenchmarks.cs
This compiles only if GenerateImposterAttribute has [AttributeUsage(AllowMultiple = true)]. Even if it does compile, the source generator may emit duplicate class definitions. The fix is to consolidate all registrations into a single file (e.g. ImposterRegistrations.cs), one attribute per type — same pattern that's cleanest for InternalsVisibleTo and similar assembly attributes.
New: Wrong matcher type in Imposter_MultipleSetups (SetupBenchmarks.cs)
// SetupBenchmarks.cs — uses Moq.It (aliased as It) with Imposter
imposter.Exists(It.IsAny<int>()).Returns(true); // ❌ Moq.It, not Imposter's Arg<T>All other Imposter setups in this PR use Arg<int>.Any(), which is Imposter's own matcher API:
imposter.Add(Arg<int>.Any(), Arg<int>.Any()).Returns(42); // ✅ consistentThis is likely a copy-paste oversight from the Mockolate or Moq setups. If Imposter's source-generated proxy doesn't accept Moq expression matchers, the setup will either silently fail to match (returning default values) or throw at runtime — either way producing misleading benchmark results. This should be:
imposter.Exists(Arg<int>.Any()).Returns(true);Summary
Two meaningful fixes landed in this update — good progress. The remaining blocker is the potential mismatched matcher in Imposter_MultipleSetups, which could cause the setup to silently not match and benchmark incorrect behavior. The duplicate [assembly: GenerateImposter] attributes are a structural concern worth cleaning up but less likely to cause runtime issues if the attribute allows multiples.
62711ac to
2263209
Compare
There was a problem hiding this comment.
Review: Add benchmarks for Imposter and Mockolate
Thanks for expanding the benchmark suite — having more source-generated mocking frameworks in the comparison is genuinely useful. The benchmark code itself is correct and follows the existing patterns well. A few things worth raising:
Duplicate attributes
The attribute for the same types is declared in multiple files. For example, appears in both and , and appears in both and , etc.
Assembly-level attributes with the same type argument will cause a compile error if they truly duplicate. At minimum this is confusing — they should be consolidated into a single file (e.g., a dedicated or alongside other globals in ). The fact that the PR currently references five separate files each declaring for overlapping types is a red flag that this may not compile cleanly.
Asymmetric benchmark design in
For , the benchmark returns (the mock wrapper object itself), while for Imposter and all other frameworks the benchmark returns the actual interface implementation (, , etc.).
If the creation cost of the proxy is amortized into the wrapper or deferred to first use, returning the wrapper instead of the proxy could make Mockolate appear artificially faster in the creation benchmark. This should be returning the actual usable object for a fair comparison.
Inconsistency in setup between Imposter and Mockolate
In , all other frameworks (TUnit.Mocks, Moq, NSubstitute, FakeItEasy) store both the mock handle and the proxied object as fields — which is the correct pattern for invocation-only benchmarks where setup overhead should be excluded via . The Imposter fields are added correctly, but is typed as and the setup calls — it's worth confirming whether actually returns something assignable to or whether it returns a wrapper that implements the interface. If it's a wrapper (same issue as above), then in the benchmark may be going through additional dispatch that the others don't.
Missing in several files
The diff removes from , , , and , replacing it with . However, the , , etc. types are still used in those files. This works because of the namespace alias, but still requires either or fully qualified names. This may already work (since is fully qualified), but it's worth double-checking that no (unqualified) usages exist that would now ambiguously resolve to from the global using.
Specifically in :
Using (Moq's matcher) in an Imposter verify call may not match correctly — Imposter uses its own matcher. If Imposter's verification doesn't understand Moq's , these verifications could silently pass or fail incorrectly, producing misleading benchmark output.
Minor: in setup benchmarks
In and , is used. The existing TUnit.Mocks, Moq, NSubstitute, and FakeItEasy variants also use , so this is consistent, but it's a minor GC allocation that happens to be identical across all implementations, so it's fine from a fairness standpoint.
Summary
The most impactful issues to address before merging:
- Consolidate declarations to avoid potential duplicate attribute issues.
- Verify returns the proxied instance, not the wrapper, for a fair comparison.
- Check that (Moq) used in Imposter verification calls actually works correctly with Imposter's argument matching — if not, use consistently.
Overall the contribution is solid and the benchmark coverage is a welcome addition to the suite.
There was a problem hiding this comment.
Review: Add benchmarks for Imposter and Mockolate
Thanks for expanding the benchmark suite — having more source-generated mocking frameworks in the comparison is genuinely useful. The benchmark code itself is correct and follows the existing patterns well. A few things worth raising:
Duplicate [assembly: GenerateImposter(...)] attributes
The GenerateImposter attribute for the same types is declared in multiple files. For example, [assembly: GenerateImposter(typeof(TUnit.Mocks.Benchmarks.ICalculatorService))] appears in both MockCreationBenchmarks.cs and SetupBenchmarks.cs, and ILogger appears in both CallbackBenchmarks.cs and CombinedWorkflowBenchmarks.cs.
Assembly-level attributes with the same type argument will cause a compile error if they truly duplicate. At minimum this is confusing — they should be consolidated into a single file (e.g., a dedicated ImposterAttributes.cs or alongside other globals in GlobalUsings.cs). Having five separate files each declaring [assembly: GenerateImposter] for overlapping types is a red flag that this may not compile cleanly.
Asymmetric benchmark design in MockCreationBenchmarks
For Mockolate_CreateMock, the benchmark returns sut (the mock wrapper object itself), while for Imposter and all other frameworks the benchmark returns the actual interface implementation (.Instance(), .Object, etc.).
If the creation cost of the proxy is amortized into the wrapper or deferred to first use, returning the wrapper instead of the proxy could make Mockolate appear artificially faster in the creation benchmark. The benchmark should return the actual usable proxied instance for a fair comparison.
Potential matcher mismatch in Imposter verification
In CombinedWorkflowBenchmarks.Imposter_FullWorkflow, Moq's It.IsAny<T>() matcher is used inside Imposter's Called() verification calls:
repoImposter.Save(It.IsAny<User>()).Called(Count.Once());
loggerImposter.Log(It.IsAny<string>(), It.IsAny<string>()).Called(Count.Once());
Imposter uses its own Arg<T>.Any() argument matchers (as used consistently throughout the rest of the Imposter benchmarks). If Imposter's verification doesn't understand Moq's It.IsAny<T>(), these verifications could silently pass regardless of actual invocations, producing misleading benchmark results. These should use Arg<T>.Any() for consistency.
Removing using Moq — potential ambiguity
The diff removes using Moq; from several files, replacing it with using It = Moq.It;. However, GlobalUsings.cs already has global using TUnit.Mocks;, which brings Mock<T> into scope as TUnit.Mocks.Mock<T>. Worth a quick scan to ensure no unqualified Moq types were inadvertently re-routed as a result of this change.
Minor: InvocationBenchmarks Mockolate field type
In InvocationBenchmarks, the Mockolate mock is stored as ICalculatorService? and used directly (rather than via a .Object or .Instance() accessor like the other frameworks). This is fine if CreateMock() returns a type implementing ICalculatorService directly, but it's worth confirming there isn't hidden wrapper dispatch happening during the invocation benchmarks.
Summary
Most impactful issues to address before merging:
- Consolidate
[assembly: GenerateImposter(...)]declarations into one file to avoid potential duplicate attribute compile errors. - Verify
Mockolate_CreateMockreturns the proxied instance (not the wrapper) for a fair comparison with other frameworks. - Replace
It.IsAny<T>()withArg<T>.Any()in Imposter verification calls inCombinedWorkflowBenchmarksto avoid potential silent false-pass verification.
Overall this is a welcome addition to the benchmark coverage.
2263209 to
0459cf8
Compare
There was a problem hiding this comment.
Follow-up Code Review
Comparing against the previous reviews — several issues have been resolved, but two concerns remain.
✅ Fixed: VerificationBenchmarks correctly calls .Instance() before invoking methods
✅ Fixed: Imposter_CreateMock now returns imposter.Instance()
✅ Fixed: CombinedWorkflowBenchmarks.Imposter_FullWorkflow uses Arg<T>.Any() consistently for Imposter verification
Still present: Duplicate [assembly: GenerateImposter(...)] attributes
The same types are still declared across multiple files:
ICalculatorService:MockCreationBenchmarks.cs,SetupBenchmarks.cs,InvocationBenchmarks.cs,VerificationBenchmarks.csIUserRepository:MockCreationBenchmarks.cs,SetupBenchmarks.cs,CombinedWorkflowBenchmarks.cs,VerificationBenchmarks.csILogger:CallbackBenchmarks.cs,CombinedWorkflowBenchmarks.csINotificationService:CallbackBenchmarks.cs
This has been flagged in every prior review. If GenerateImposterAttribute has [AttributeUsage(AllowMultiple = true)], it compiles — but the source generator may still emit duplicate class definitions for the same interface, causing build errors. The correct architectural fix is to consolidate all of these into a single file (e.g., ImposterRegistrations.cs), exactly as you'd consolidate [assembly: InternalsVisibleTo] attributes. Each interface should appear exactly once.
Still present: Wrong matcher in Mockolate_MultipleSetups (SetupBenchmarks.cs)
The file has using It = Moq.It;, so It.IsAny<int>() is Moq.It.IsAny<int>(). All other Mockolate setups in this file and the rest of the PR use Mockolate.It.IsAny<T>() (fully qualified):
This was flagged in the previous review. If Mockolate's source-generated proxy uses runtime matcher inspection (not compile-time code generation), then passing Moq.It.IsAny<int>() into a Mockolate setup will silently fail to match — the mock returns the default value instead of true, and the benchmark measures a partially-broken configuration. Fix:
Summary
Three rounds of fixes have landed — good progress, and the overall benchmark structure is solid. The two remaining issues are both carryovers from earlier reviews:
- Consolidate
[assembly: GenerateImposter(...)]into one file — avoids potential duplicate code generation. - Fix
Mockolate.ItvsMoq.ItinMockolate_MultipleSetups— ensures the setup actually registers the return value and the benchmark measures correct behavior.
There was a problem hiding this comment.
Follow-up Code Review
Comparing against the previous reviews — several issues have been resolved, but two concerns remain.
✅ Fixed: VerificationBenchmarks correctly calls .Instance() before invoking methods
✅ Fixed: Imposter_CreateMock now returns imposter.Instance()
✅ Fixed: CombinedWorkflowBenchmarks.Imposter_FullWorkflow uses Arg<T>.Any() consistently for Imposter verification
Still present: Duplicate [assembly: GenerateImposter(...)] attributes
The same types are still declared across multiple files:
ICalculatorService:MockCreationBenchmarks.cs,SetupBenchmarks.cs,InvocationBenchmarks.cs,VerificationBenchmarks.csIUserRepository:MockCreationBenchmarks.cs,SetupBenchmarks.cs,CombinedWorkflowBenchmarks.cs,VerificationBenchmarks.csILogger:CallbackBenchmarks.cs,CombinedWorkflowBenchmarks.csINotificationService:CallbackBenchmarks.cs
This has been flagged in every prior review. If GenerateImposterAttribute has [AttributeUsage(AllowMultiple = true)], it compiles — but the source generator may still emit duplicate class definitions for the same interface, causing build errors. The correct fix is to consolidate all of these into a single file (e.g., ImposterRegistrations.cs), exactly as you'd consolidate [assembly: InternalsVisibleTo] attributes. Each interface should appear exactly once.
Still present: Wrong matcher in Mockolate_MultipleSetups (SetupBenchmarks.cs)
The file has using It = Moq.It;, so unqualified It.IsAny<int>() resolves to Moq.It.IsAny<int>(). All other Mockolate setups in this PR use fully-qualified Mockolate.It.IsAny<T>(), but this line uses the alias:
sut.Mock.Setup.Exists(It.IsAny<int>()).Returns(true); // ❌ Moq.It, not Mockolate.It
If Mockolate's runtime matcher inspection doesn't recognize Moq.It.IsAny<int>(), this setup silently fails to match — the mock returns the default value instead of true. The fix is straightforward:
sut.Mock.Setup.Exists(Mockolate.It.IsAny<int>()).Returns(true);
Summary
Three rounds of fixes have landed — good progress, and the overall benchmark structure is solid. The two remaining issues are both carryovers from earlier reviews:
- Consolidate
[assembly: GenerateImposter(...)]into one file — avoids potential duplicate code generation. - Fix
Mockolate.ItvsMoq.ItinMockolate_MultipleSetups— ensures the setup registers the return value correctly.
0459cf8 to
707e849
Compare
There was a problem hiding this comment.
Review: Add benchmarks for Imposter and Mockolate mocking frameworks
Overall this is a solid, clean addition. The benchmarks follow the existing patterns well and cover all the same scenarios as the other frameworks. A few observations and suggestions:
Potential benchmark validity concern: Imposter_VerifyNever
In VerificationBenchmarks.cs, the Imposter "Never" benchmark does not instantiate the mock (no .Instance() call) before verifying, which may not fully match the other frameworks' patterns that instantiate the mock even if they never call it:
[Benchmark(Description = "Imposter (Never)")]
public void Imposter_VerifyNever()
{
var imposter = ICalculatorService.Imposter();
imposter.Format(Arg<int>.Any()).Called(Count.Never());
// No: var calc = imposter.Instance();
}For fair comparison, check whether instantiation is required for verification and whether the other frameworks' "Never" benchmarks do more work (e.g., Moq creates the mock but also calls mock.Verify(...) without instantiating .Object). If Imposter requires instantiation to track calls, this could report misleadingly fast results.
Inconsistency: Mockolate_CreateMock returns the mock wrapper, not the underlying object
In MockCreationBenchmarks.cs, most benchmarks return the usable object:
// Imposter - returns the instance (the callable object)
public object Imposter_CreateMock()
{
var imposter = ICalculatorService.Imposter();
return imposter.Instance();
}
// Mockolate - returns the mock wrapper directly (includes Mock property etc.)
public object Mockolate_CreateMock()
{
var sut = ICalculatorService.CreateMock();
return sut; // This is a wrapper type, not ICalculatorService
}Since ICalculatorService.CreateMock() returns a type that implements ICalculatorService plus a Mock property, returning it directly may be fine — but it's worth confirming whether the returned object is the interface implementation itself or an additional wrapper, so the benchmark measures the same conceptual operation as the other frameworks.
new List<User>() allocations in setup benchmarks
In SetupBenchmarks.Mockolate_MultipleSetups and Imposter_MultipleSetups, new List<User>() is allocated inside the benchmark method (matching the pattern of the other frameworks). This is consistent, but worth noting since BenchmarkDotNet with [MemoryDiagnoser] will attribute those allocations to the mock framework being measured. All frameworks do this equivalently, so comparison is fair — just something to be aware of when reading results.
Minor: ImposterRegistrations.cs placement
The new ImposterRegistrations.cs file uses [assembly: GenerateImposter(...)] attributes which is the correct source-generator approach for Imposter. This is clean and follows AOT-compatible patterns. No issues here.
Qualified Moq.It references
The PR correctly qualifies the existing It.IsAny<T>() calls to Moq.It.IsAny<T>() to resolve ambiguity with the new Mockolate.It type. These are necessary fixups and look correct.
Summary
The implementation is straightforward and consistent with the existing benchmark structure. The main thing worth double-checking is the Imposter_VerifyNever scenario to ensure it's measuring a comparable operation to the other "Never" verification benchmarks. Everything else looks good.
Updated [TUnit](https://github.com/thomhurst/TUnit) from 1.21.30 to 1.23.7. <details> <summary>Release notes</summary> _Sourced from [TUnit's releases](https://github.com/thomhurst/TUnit/releases)._ ## 1.23.7 <!-- Release notes generated using configuration in .github/release.yml at v1.23.7 --> ## What's Changed ### Other Changes * feat: use results directory provided by Microsoft Testing Platform in HtmlReporter by @DavidZidar in thomhurst/TUnit#5294 * feat: add benchmarks for Imposter and Mockolate mocking frameworks by @vbreuss in thomhurst/TUnit#5295 * feat: add TUnit0080 analyzer for missing polyfill types by @thomhurst in thomhurst/TUnit#5292 * fix: respect user-set TUnitImplicitUsings from Directory.Build.props by @thomhurst in thomhurst/TUnit#5280 * perf: optimize TUnit.Mocks hot paths by @thomhurst in thomhurst/TUnit#5300 ### Dependencies * chore(deps): update tunit to 1.22.19 by @thomhurst in thomhurst/TUnit#5296 ## New Contributors * @DavidZidar made their first contribution in thomhurst/TUnit#5294 **Full Changelog**: thomhurst/TUnit@v1.22.19...v1.23.7 ## 1.22.19 <!-- Release notes generated using configuration in .github/release.yml at v1.22.19 --> ## What's Changed ### Other Changes * Add mock library benchmarks: TUnit.Mocks vs Moq, NSubstitute, FakeItEasy by @Copilot in thomhurst/TUnit#5284 * perf: lazily initialize optional MockEngine collections by @thomhurst in thomhurst/TUnit#5289 * Always emit TUnit.Mocks.Generated namespace from source generator by @Copilot in thomhurst/TUnit#5282 ### Dependencies * chore(deps): update tunit to 1.22.6 by @thomhurst in thomhurst/TUnit#5285 **Full Changelog**: thomhurst/TUnit@v1.22.6...v1.22.19 ## 1.22.6 <!-- Release notes generated using configuration in .github/release.yml at v1.22.6 --> ## What's Changed ### Other Changes * fix: use IComputeResource to filter waitable Aspire resources by @thomhurst in thomhurst/TUnit#5278 * fix: preserve StateBag when creating per-test TestBuilderContext by @thomhurst in thomhurst/TUnit#5279 ### Dependencies * chore(deps): update tunit to 1.22.3 by @thomhurst in thomhurst/TUnit#5275 **Full Changelog**: thomhurst/TUnit@v1.22.3...v1.22.6 ## 1.22.3 <!-- Release notes generated using configuration in .github/release.yml at v1.22.3 --> ## What's Changed ### Other Changes * fix: pass assembly version properties to dotnet pack by @thomhurst in thomhurst/TUnit#5274 ### Dependencies * chore(deps): update tunit to 1.22.0 by @thomhurst in thomhurst/TUnit#5272 **Full Changelog**: thomhurst/TUnit@v1.22.0...v1.22.3 ## 1.22.0 <!-- Release notes generated using configuration in .github/release.yml at v1.22.0 --> ## What's Changed ### Other Changes * perf: run GitVersion once in CI instead of per-project by @slang25 in thomhurst/TUnit#5259 * perf: disable GitVersion MSBuild task globally by @thomhurst in thomhurst/TUnit#5266 * fix: skip IResourceWithoutLifetime resources in Aspire fixture wait logic by @thomhurst in thomhurst/TUnit#5268 * fix: relax docs site Node.js engine constraint to >=24 by @thomhurst in thomhurst/TUnit#5269 * fix: catch unhandled exceptions in ExecuteRequestAsync to prevent IDE RPC crashes by @thomhurst in thomhurst/TUnit#5271 * feat: register HTML report as MTP session artifact by @thomhurst in thomhurst/TUnit#5270 ### Dependencies * chore(deps): update tunit to 1.21.30 by @thomhurst in thomhurst/TUnit#5254 * chore(deps): update opentelemetry to 1.15.1 by @thomhurst in thomhurst/TUnit#5258 * chore(deps): bump node-forge from 1.3.1 to 1.4.0 in /docs by @dependabot[bot] in thomhurst/TUnit#5255 * chore(deps): bump picomatch from 2.3.1 to 2.3.2 in /docs by @dependabot[bot] in thomhurst/TUnit#5256 * chore(deps): update react by @thomhurst in thomhurst/TUnit#5261 * chore(deps): update node.js to >=18.20.8 by @thomhurst in thomhurst/TUnit#5262 * chore(deps): update node.js to v24 by @thomhurst in thomhurst/TUnit#5264 **Full Changelog**: thomhurst/TUnit@v1.21.30...v1.22.0 Commits viewable in [compare view](thomhurst/TUnit@v1.21.30...v1.23.7). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Updated [TUnit.Core](https://github.com/thomhurst/TUnit) from 1.21.6 to 1.23.7. <details> <summary>Release notes</summary> _Sourced from [TUnit.Core's releases](https://github.com/thomhurst/TUnit/releases)._ ## 1.23.7 <!-- Release notes generated using configuration in .github/release.yml at v1.23.7 --> ## What's Changed ### Other Changes * feat: use results directory provided by Microsoft Testing Platform in HtmlReporter by @DavidZidar in thomhurst/TUnit#5294 * feat: add benchmarks for Imposter and Mockolate mocking frameworks by @vbreuss in thomhurst/TUnit#5295 * feat: add TUnit0080 analyzer for missing polyfill types by @thomhurst in thomhurst/TUnit#5292 * fix: respect user-set TUnitImplicitUsings from Directory.Build.props by @thomhurst in thomhurst/TUnit#5280 * perf: optimize TUnit.Mocks hot paths by @thomhurst in thomhurst/TUnit#5300 ### Dependencies * chore(deps): update tunit to 1.22.19 by @thomhurst in thomhurst/TUnit#5296 ## New Contributors * @DavidZidar made their first contribution in thomhurst/TUnit#5294 **Full Changelog**: thomhurst/TUnit@v1.22.19...v1.23.7 ## 1.22.19 <!-- Release notes generated using configuration in .github/release.yml at v1.22.19 --> ## What's Changed ### Other Changes * Add mock library benchmarks: TUnit.Mocks vs Moq, NSubstitute, FakeItEasy by @Copilot in thomhurst/TUnit#5284 * perf: lazily initialize optional MockEngine collections by @thomhurst in thomhurst/TUnit#5289 * Always emit TUnit.Mocks.Generated namespace from source generator by @Copilot in thomhurst/TUnit#5282 ### Dependencies * chore(deps): update tunit to 1.22.6 by @thomhurst in thomhurst/TUnit#5285 **Full Changelog**: thomhurst/TUnit@v1.22.6...v1.22.19 ## 1.22.6 <!-- Release notes generated using configuration in .github/release.yml at v1.22.6 --> ## What's Changed ### Other Changes * fix: use IComputeResource to filter waitable Aspire resources by @thomhurst in thomhurst/TUnit#5278 * fix: preserve StateBag when creating per-test TestBuilderContext by @thomhurst in thomhurst/TUnit#5279 ### Dependencies * chore(deps): update tunit to 1.22.3 by @thomhurst in thomhurst/TUnit#5275 **Full Changelog**: thomhurst/TUnit@v1.22.3...v1.22.6 ## 1.22.3 <!-- Release notes generated using configuration in .github/release.yml at v1.22.3 --> ## What's Changed ### Other Changes * fix: pass assembly version properties to dotnet pack by @thomhurst in thomhurst/TUnit#5274 ### Dependencies * chore(deps): update tunit to 1.22.0 by @thomhurst in thomhurst/TUnit#5272 **Full Changelog**: thomhurst/TUnit@v1.22.0...v1.22.3 ## 1.22.0 <!-- Release notes generated using configuration in .github/release.yml at v1.22.0 --> ## What's Changed ### Other Changes * perf: run GitVersion once in CI instead of per-project by @slang25 in thomhurst/TUnit#5259 * perf: disable GitVersion MSBuild task globally by @thomhurst in thomhurst/TUnit#5266 * fix: skip IResourceWithoutLifetime resources in Aspire fixture wait logic by @thomhurst in thomhurst/TUnit#5268 * fix: relax docs site Node.js engine constraint to >=24 by @thomhurst in thomhurst/TUnit#5269 * fix: catch unhandled exceptions in ExecuteRequestAsync to prevent IDE RPC crashes by @thomhurst in thomhurst/TUnit#5271 * feat: register HTML report as MTP session artifact by @thomhurst in thomhurst/TUnit#5270 ### Dependencies * chore(deps): update tunit to 1.21.30 by @thomhurst in thomhurst/TUnit#5254 * chore(deps): update opentelemetry to 1.15.1 by @thomhurst in thomhurst/TUnit#5258 * chore(deps): bump node-forge from 1.3.1 to 1.4.0 in /docs by @dependabot[bot] in thomhurst/TUnit#5255 * chore(deps): bump picomatch from 2.3.1 to 2.3.2 in /docs by @dependabot[bot] in thomhurst/TUnit#5256 * chore(deps): update react by @thomhurst in thomhurst/TUnit#5261 * chore(deps): update node.js to >=18.20.8 by @thomhurst in thomhurst/TUnit#5262 * chore(deps): update node.js to v24 by @thomhurst in thomhurst/TUnit#5264 **Full Changelog**: thomhurst/TUnit@v1.21.30...v1.22.0 ## 1.21.30 <!-- Release notes generated using configuration in .github/release.yml at v1.21.30 --> ## What's Changed ### Other Changes * feat: add test discovery Activity span for tracing by @thomhurst in thomhurst/TUnit#5246 * Fix mock generator not preserving nullable annotations on reference types by @Copilot in thomhurst/TUnit#5251 * Fix ITestSkippedEventReceiver not firing for [Skip]-attributed tests by @thomhurst in thomhurst/TUnit#5253 * Use CallerArgumentExpression for TestDataRow by default. by @m-gasser in thomhurst/TUnit#5135 ### Dependencies * chore(deps): update tunit to 1.21.24 by @thomhurst in thomhurst/TUnit#5247 **Full Changelog**: thomhurst/TUnit@v1.21.24...v1.21.30 ## 1.21.24 <!-- Release notes generated using configuration in .github/release.yml at v1.21.24 --> ## What's Changed ### Other Changes * Fix OpenTelemetry missing root span by reordering session activity lifecycle by @Copilot in thomhurst/TUnit#5245 ### Dependencies * chore(deps): update tunit to 1.21.20 by @thomhurst in thomhurst/TUnit#5241 * chore(deps): update dependency stackexchange.redis to 2.12.8 by @thomhurst in thomhurst/TUnit#5243 **Full Changelog**: thomhurst/TUnit@v1.21.20...v1.21.24 ## 1.21.20 <!-- Release notes generated using configuration in .github/release.yml at v1.21.20 --> ## What's Changed ### Other Changes * fix: respect TUnitImplicitUsings set in Directory.Build.props by @thomhurst in thomhurst/TUnit#5225 * feat: covariant assertions for interfaces and non-sealed classes by @thomhurst in thomhurst/TUnit#5226 * feat: support string-to-parseable type conversions in [Arguments] by @thomhurst in thomhurst/TUnit#5227 * feat: add string length range assertions by @thomhurst in thomhurst/TUnit#4935 * Fix BeforeEvery/AfterEvery hooks for Class and Assembly not being executed by @Copilot in thomhurst/TUnit#5239 ### Dependencies * chore(deps): update tunit to 1.21.6 by @thomhurst in thomhurst/TUnit#5228 * chore(deps): update dependency gitversion.msbuild to 6.7.0 by @thomhurst in thomhurst/TUnit#5229 * chore(deps): update dependency gitversion.tool to v6.7.0 by @thomhurst in thomhurst/TUnit#5230 * chore(deps): update aspire to 13.2.0 - autoclosed by @thomhurst in thomhurst/TUnit#5232 * chore(deps): update dependency typescript to v6 by @thomhurst in thomhurst/TUnit#5233 * chore(deps): update dependency polyfill to 9.23.0 by @thomhurst in thomhurst/TUnit#5235 * chore(deps): update dependency polyfill to 9.23.0 by @thomhurst in thomhurst/TUnit#5236 **Full Changelog**: thomhurst/TUnit@v1.21.6...v1.21.20 Commits viewable in [compare view](thomhurst/TUnit@v1.21.6...v1.23.7). </details> [](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) --- <details> <summary>Dependabot commands and options</summary> <br /> You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) </details> Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Description
This pull request expands the mocking libraries benchmarked in the
TUnit.Mocks.Benchmarksproject with two other source-generated mocking frameworks:ImposterMockolateIt introduces new benchmarks for these frameworks across all scenarios (mock creation, setup, invocation, callbacks, verification, and combined workflows) to provide a fair comparison between the libraries.
Related Issue
Fixes #
Type of Change
Checklist
Required
TUnit-Specific Requirements
TUnit.Core.SourceGenerator)TUnit.Engine)TUnit.Core.SourceGenerator.Testsand/orTUnit.PublicAPItests.received.txtfiles and accepted them as.verified.txt.verified.txtfiles[DynamicallyAccessedMembers]annotationsdotnet publish -p:PublishAot=trueTesting
dotnet test)Additional Notes