diff --git a/TUnit.Mocks.Assertions/MockAssertionExtensions.cs b/TUnit.Mocks.Assertions/MockAssertionExtensions.cs index 296582627f..98dd817347 100644 --- a/TUnit.Mocks.Assertions/MockAssertionExtensions.cs +++ b/TUnit.Mocks.Assertions/MockAssertionExtensions.cs @@ -6,7 +6,7 @@ namespace TUnit.Mocks.Assertions; /// /// Extension methods for asserting mock call verification through the TUnit assertion pipeline. -/// Enables: await Assert.That(mock.Verify.Method()).WasCalled(Times.Once); +/// Enables: await Assert.That(mock.Method()).WasCalled(Times.Once); /// public static class MockAssertionExtensions { @@ -24,7 +24,7 @@ public static WasCalledAssertion WasCalled( /// /// Asserts that the mock member was called the specified number of times. - /// Generic overload for types implementing (e.g. PropertyVerifyAccessor). + /// Generic overload for types implementing (e.g. PropertyMockCall). /// public static WasCalledAssertion WasCalled( this IAssertionSource source, @@ -48,7 +48,7 @@ public static WasNeverCalledAssertion WasNeverCalled( /// /// Asserts that the mock member was never called. - /// Generic overload for types implementing (e.g. PropertyVerifyAccessor). + /// Generic overload for types implementing (e.g. PropertyMockCall). /// public static WasNeverCalledAssertion WasNeverCalled( this IAssertionSource source) where T : ICallVerification diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt index 76d191b179..519639f46b 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_Inheriting_Multiple_Interfaces.verified.txt @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IReadWriter_MockImpl(engine); engine.Raisable = impl; - var setup = new IReadWriter_MockSetup(engine); - var verify = new IReadWriter_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -72,121 +70,99 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IReadWriter_MockSetup : global::TUnit.Mocks.IMockSetup + public static class IReadWriter_MockMemberExtensions { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IReadWriter_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IReadWriter_MockSetupExtensions - { - public static global::TUnit.Mocks.Setup.IVoidMethodSetup Flush(this global::TUnit.Mocks.IMockSetup setup) + public static global::TUnit.Mocks.VoidMockMethodCall Flush(this global::TUnit.Mocks.Mock mock) { - var s = (IReadWriter_MockSetup)setup; var matchers = global::System.Array.Empty(); - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "Flush"); - s.Engine.AddSetup(methodSetup); - return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup); + return new global::TUnit.Mocks.VoidMockMethodCall(mock.Engine, 0, "Flush", matchers); } - public static global::TUnit.Mocks.Setup.IMethodSetup Read(this global::TUnit.Mocks.IMockSetup setup) + public static global::TUnit.Mocks.MockMethodCall Read(this global::TUnit.Mocks.Mock mock) { - var s = (IReadWriter_MockSetup)setup; var matchers = global::System.Array.Empty(); - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(1, matchers, "Read"); - s.Engine.AddSetup(methodSetup); - return new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup); + return new global::TUnit.Mocks.MockMethodCall(mock.Engine, 1, "Read", matchers); } - public static IReadWriter_Write_M2_TypedSetup Write(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg data) + public static IReadWriter_Write_M2_MockCall Write(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg data) { - var s = (IReadWriter_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { data.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(2, matchers, "Write"); - s.Engine.AddSetup(methodSetup); - return new IReadWriter_Write_M2_TypedSetup(new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup)); + return new IReadWriter_Write_M2_MockCall(mock.Engine, 2, "Write", matchers); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IReadWriter_Write_M2_TypedSetup + public sealed class IReadWriter_Write_M2_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy _lazyBuilder; + + internal IReadWriter_Write_M2_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(setup); + } + ); + _ = _lazyBuilder.Value; + } - internal IReadWriter_Write_M2_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.VoidMethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IReadWriter_Write_M2_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IReadWriter_Write_M2_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IReadWriter_Write_M2_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IReadWriter_Write_M2_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IReadWriter_Write_M2_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IReadWriter_Write_M2_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IReadWriter_Write_M2_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IReadWriter_Write_M2_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IReadWriter_Write_M2_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IReadWriter_Write_M2_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IReadWriter_Write_M2_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IReadWriter_Write_M2_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IReadWriter_Write_M2_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IReadWriter_Write_M2_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IReadWriter_Write_M2_TypedSetup Then() { _inner.Then(); return this; } + public IReadWriter_Write_M2_MockCall Then() { EnsureSetup().Then(); return this; } /// Execute a typed callback using the actual method parameters. - public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action callback) + public IReadWriter_Write_M2_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!)); + EnsureSetup().Callback(args => callback((string)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IReadWriter_Write_M2_TypedSetup Throws(global::System.Func exceptionFactory) + public IReadWriter_Write_M2_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!)); return this; } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class IReadWriter_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IReadWriter_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IReadWriter_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification Flush(this global::TUnit.Mocks.IMockVerify verify) - { - var v = (IReadWriter_MockVerify)verify; - var matchers = global::System.Array.Empty(); - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "Flush", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification Read(this global::TUnit.Mocks.IMockVerify verify) - { - var v = (IReadWriter_MockVerify)verify; - var matchers = global::System.Array.Empty(); - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 1, "Read", matchers); - } - public static global::TUnit.Mocks.Verification.ICallVerification Write(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg data) - { - var v = (IReadWriter_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { data.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 2, "Write", matchers); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt index 2b556f7a56..1518968e91 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Async_Methods.verified.txt @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IAsyncService_MockImpl(engine); engine.Raisable = impl; - var setup = new IAsyncService_MockSetup(engine); - var verify = new IAsyncService_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -109,249 +107,283 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IAsyncService_MockSetup : global::TUnit.Mocks.IMockSetup + public static class IAsyncService_MockMemberExtensions { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IAsyncService_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IAsyncService_MockSetupExtensions - { - public static IAsyncService_GetValueAsync_M0_TypedSetup GetValueAsync(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg key) + public static IAsyncService_GetValueAsync_M0_MockCall GetValueAsync(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg key) { - var s = (IAsyncService_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { key.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "GetValueAsync"); - s.Engine.AddSetup(methodSetup); - return new IAsyncService_GetValueAsync_M0_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IAsyncService_GetValueAsync_M0_MockCall(mock.Engine, 0, "GetValueAsync", matchers); } - public static global::TUnit.Mocks.Setup.IVoidMethodSetup DoWorkAsync(this global::TUnit.Mocks.IMockSetup setup) + public static global::TUnit.Mocks.VoidMockMethodCall DoWorkAsync(this global::TUnit.Mocks.Mock mock) { - var s = (IAsyncService_MockSetup)setup; var matchers = global::System.Array.Empty(); - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(1, matchers, "DoWorkAsync"); - s.Engine.AddSetup(methodSetup); - return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup); + return new global::TUnit.Mocks.VoidMockMethodCall(mock.Engine, 1, "DoWorkAsync", matchers); } - public static IAsyncService_ComputeAsync_M2_TypedSetup ComputeAsync(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg input) + public static IAsyncService_ComputeAsync_M2_MockCall ComputeAsync(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg input) { - var s = (IAsyncService_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { input.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(2, matchers, "ComputeAsync"); - s.Engine.AddSetup(methodSetup); - return new IAsyncService_ComputeAsync_M2_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IAsyncService_ComputeAsync_M2_MockCall(mock.Engine, 2, "ComputeAsync", matchers); } - public static IAsyncService_InitializeAsync_M3_TypedSetup InitializeAsync(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg ct) + public static IAsyncService_InitializeAsync_M3_MockCall InitializeAsync(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg ct) { - var s = (IAsyncService_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { ct.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(3, matchers, "InitializeAsync"); - s.Engine.AddSetup(methodSetup); - return new IAsyncService_InitializeAsync_M3_TypedSetup(new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup)); + return new IAsyncService_InitializeAsync_M3_MockCall(mock.Engine, 3, "InitializeAsync", matchers); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IAsyncService_GetValueAsync_M0_TypedSetup + public sealed class IAsyncService_GetValueAsync_M0_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; + + internal IAsyncService_GetValueAsync_M0_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } - internal IAsyncService_GetValueAsync_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IAsyncService_GetValueAsync_M0_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Returns(string value) { EnsureSetup().Returns(value); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } + public IAsyncService_GetValueAsync_M0_MockCall ReturnsSequentially(params string[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IAsyncService_GetValueAsync_M0_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IAsyncService_GetValueAsync_M0_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IAsyncService_GetValueAsync_M0_TypedSetup Then() { _inner.Then(); return this; } + public IAsyncService_GetValueAsync_M0_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IAsyncService_GetValueAsync_M0_TypedSetup Returns(global::System.Func factory) + public IAsyncService_GetValueAsync_M0_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((string)args[0]!)); + EnsureSetup().Returns(args => factory((string)args[0]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IAsyncService_GetValueAsync_M0_TypedSetup Callback(global::System.Action callback) + public IAsyncService_GetValueAsync_M0_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!)); + EnsureSetup().Callback(args => callback((string)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IAsyncService_GetValueAsync_M0_TypedSetup Throws(global::System.Func exceptionFactory) + public IAsyncService_GetValueAsync_M0_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!)); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IAsyncService_ComputeAsync_M2_TypedSetup + public sealed class IAsyncService_ComputeAsync_M2_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; + + internal IAsyncService_ComputeAsync_M2_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } - internal IAsyncService_ComputeAsync_M2_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IAsyncService_ComputeAsync_M2_TypedSetup Returns(int value) { _inner.Returns(value); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Returns(int value) { EnsureSetup().Returns(value); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup ReturnsSequentially(params int[] values) { _inner.ReturnsSequentially(values); return this; } + public IAsyncService_ComputeAsync_M2_MockCall ReturnsSequentially(params int[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IAsyncService_ComputeAsync_M2_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IAsyncService_ComputeAsync_M2_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IAsyncService_ComputeAsync_M2_TypedSetup Then() { _inner.Then(); return this; } + public IAsyncService_ComputeAsync_M2_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IAsyncService_ComputeAsync_M2_TypedSetup Returns(global::System.Func factory) + public IAsyncService_ComputeAsync_M2_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((int)args[0]!)); + EnsureSetup().Returns(args => factory((int)args[0]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IAsyncService_ComputeAsync_M2_TypedSetup Callback(global::System.Action callback) + public IAsyncService_ComputeAsync_M2_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((int)args[0]!)); + EnsureSetup().Callback(args => callback((int)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IAsyncService_ComputeAsync_M2_TypedSetup Throws(global::System.Func exceptionFactory) + public IAsyncService_ComputeAsync_M2_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((int)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((int)args[0]!)); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IAsyncService_InitializeAsync_M3_TypedSetup + public sealed class IAsyncService_InitializeAsync_M3_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy _lazyBuilder; + + internal IAsyncService_InitializeAsync_M3_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(setup); + } + ); + _ = _lazyBuilder.Value; + } - internal IAsyncService_InitializeAsync_M3_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.VoidMethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IAsyncService_InitializeAsync_M3_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IAsyncService_InitializeAsync_M3_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IAsyncService_InitializeAsync_M3_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IAsyncService_InitializeAsync_M3_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IAsyncService_InitializeAsync_M3_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IAsyncService_InitializeAsync_M3_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IAsyncService_InitializeAsync_M3_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IAsyncService_InitializeAsync_M3_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IAsyncService_InitializeAsync_M3_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IAsyncService_InitializeAsync_M3_TypedSetup Then() { _inner.Then(); return this; } + public IAsyncService_InitializeAsync_M3_MockCall Then() { EnsureSetup().Then(); return this; } /// Execute a typed callback using the actual method parameters. - public IAsyncService_InitializeAsync_M3_TypedSetup Callback(global::System.Action callback) + public IAsyncService_InitializeAsync_M3_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((global::System.Threading.CancellationToken)args[0]!)); + EnsureSetup().Callback(args => callback((global::System.Threading.CancellationToken)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IAsyncService_InitializeAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) + public IAsyncService_InitializeAsync_M3_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((global::System.Threading.CancellationToken)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((global::System.Threading.CancellationToken)args[0]!)); return this; } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class IAsyncService_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IAsyncService_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IAsyncService_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification GetValueAsync(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg key) - { - var v = (IAsyncService_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { key.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "GetValueAsync", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification DoWorkAsync(this global::TUnit.Mocks.IMockVerify verify) - { - var v = (IAsyncService_MockVerify)verify; - var matchers = global::System.Array.Empty(); - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 1, "DoWorkAsync", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification ComputeAsync(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg input) - { - var v = (IAsyncService_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { input.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 2, "ComputeAsync", matchers); - } - public static global::TUnit.Mocks.Verification.ICallVerification InitializeAsync(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg ct) - { - var v = (IAsyncService_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { ct.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 3, "InitializeAsync", matchers); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt index 72a7e0786e..be44e45cc5 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Events.verified.txt @@ -47,10 +47,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new INotifier_MockImpl(engine); engine.Raisable = impl; - var setup = new INotifier_MockSetup(engine); - var verify = new INotifier_MockVerify(engine); - var raise = new INotifier_MockRaise(impl); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, raise, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -115,131 +112,95 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class INotifier_MockRaise : global::TUnit.Mocks.IMockRaise + public static class INotifier_MockMemberExtensions { - internal readonly INotifier_MockImpl Impl; - - internal INotifier_MockRaise(INotifier_MockImpl impl) => Impl = impl; - } - - public static class INotifier_MockRaiseExtensions - { - public static void ItemAdded(this global::TUnit.Mocks.IMockRaise raise, string e) + public static INotifier_Notify_M0_MockCall Notify(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg message) { - var r = (INotifier_MockRaise)raise; - r.Impl.Raise_ItemAdded(e); + var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { message.Matcher }; + return new INotifier_Notify_M0_MockCall(mock.Engine, 0, "Notify", matchers); } - } -} - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class INotifier_MockSetup : global::TUnit.Mocks.IMockSetup - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal INotifier_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class INotifier_MockSetupExtensions - { - public static INotifier_Notify_M0_TypedSetup Notify(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg message) + public static void RaiseItemAdded(this global::TUnit.Mocks.Mock mock, string e) { - var s = (INotifier_MockSetup)setup; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { message.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "Notify"); - s.Engine.AddSetup(methodSetup); - return new INotifier_Notify_M0_TypedSetup(new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup)); + ((global::TUnit.Mocks.IRaisable)mock.Engine.Raisable!).RaiseEvent("ItemAdded", (object?)e); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct INotifier_Notify_M0_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup, global::TUnit.Mocks.Setup.IVoidSetupChain + public sealed class INotifier_Notify_M0_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; - - internal INotifier_Notify_M0_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy _lazyBuilder; - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws() => _inner.Throws(); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Exception exception) => _inner.Throws(exception); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Raises(string eventName, object? args) => _inner.Raises(eventName, args); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + internal INotifier_Notify_M0_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(setup); + } + ); + _ = _lazyBuilder.Value; + } - global::TUnit.Mocks.Setup.IVoidMethodSetup global::TUnit.Mocks.Setup.IVoidSetupChain.Then() { _inner.Then(); return this; } - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.Raises(string eventName, object? args) => _inner.Raises(eventName, args); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + private global::TUnit.Mocks.Setup.VoidMethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public INotifier_Notify_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public INotifier_Notify_M0_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public INotifier_Notify_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public INotifier_Notify_M0_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public INotifier_Notify_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public INotifier_Notify_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public INotifier_Notify_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public INotifier_Notify_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public INotifier_Notify_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public INotifier_Notify_M0_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public INotifier_Notify_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public INotifier_Notify_M0_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public INotifier_Notify_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public INotifier_Notify_M0_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public INotifier_Notify_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public INotifier_Notify_M0_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public INotifier_Notify_M0_TypedSetup Then() { _inner.Then(); return this; } + public INotifier_Notify_M0_MockCall Then() { EnsureSetup().Then(); return this; } /// Execute a typed callback using the actual method parameters. - public INotifier_Notify_M0_TypedSetup Callback(global::System.Action callback) + public INotifier_Notify_M0_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!)); + EnsureSetup().Callback(args => callback((string)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public INotifier_Notify_M0_TypedSetup Throws(global::System.Func exceptionFactory) + public INotifier_Notify_M0_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!)); return this; } /// Auto-raise the ItemAdded event when this method is called. - public INotifier_Notify_M0_TypedSetup RaisesItemAdded(string e) { _inner.Raises("ItemAdded", (object?)e); return this; } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class INotifier_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal INotifier_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } + public INotifier_Notify_M0_MockCall RaisesItemAdded(string e) { EnsureSetup().Raises("ItemAdded", (object?)e); return this; } - public static class INotifier_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification Notify(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg message) - { - var v = (INotifier_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { message.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "Notify", matchers); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Generic_Methods.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Generic_Methods.verified.txt index 2638bad06f..dbf5e5a4d3 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Generic_Methods.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Generic_Methods.verified.txt @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IRepository_MockImpl(engine); engine.Raisable = impl; - var setup = new IRepository_MockSetup(engine); - var verify = new IRepository_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -72,80 +70,24 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IRepository_MockSetup : global::TUnit.Mocks.IMockSetup + public static class IRepository_MockMemberExtensions { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IRepository_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IRepository_MockSetupExtensions - { - public static global::TUnit.Mocks.Setup.IMethodSetup GetById(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg id) where T : class - { - var s = (IRepository_MockSetup)setup; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { id.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "GetById"); - s.Engine.AddSetup(methodSetup); - return new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup); - } - - public static global::TUnit.Mocks.Setup.IVoidMethodSetup Save(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg entity) where T : class, new() - { - var s = (IRepository_MockSetup)setup; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { entity.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(1, matchers, "Save"); - s.Engine.AddSetup(methodSetup); - return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup); - } - - public static global::TUnit.Mocks.Setup.IMethodSetup Transform(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg input) where TInput : notnull where TResult : struct - { - var s = (IRepository_MockSetup)setup; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { input.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(2, matchers, "Transform"); - s.Engine.AddSetup(methodSetup); - return new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup); - } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class IRepository_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IRepository_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IRepository_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification GetById(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg id) where T : class + public static global::TUnit.Mocks.MockMethodCall GetById(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg id) where T : class { - var v = (IRepository_MockVerify)verify; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { id.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "GetById", matchers); + return new global::TUnit.Mocks.MockMethodCall(mock.Engine, 0, "GetById", matchers); } - public static global::TUnit.Mocks.Verification.ICallVerification Save(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg entity) where T : class, new() + public static global::TUnit.Mocks.VoidMockMethodCall Save(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg entity) where T : class, new() { - var v = (IRepository_MockVerify)verify; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { entity.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 1, "Save", matchers); + return new global::TUnit.Mocks.VoidMockMethodCall(mock.Engine, 1, "Save", matchers); } - public static global::TUnit.Mocks.Verification.ICallVerification Transform(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg input) where TInput : notnull where TResult : struct + public static global::TUnit.Mocks.MockMethodCall Transform(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg input) where TInput : notnull where TResult : struct { - var v = (IRepository_MockVerify)verify; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { input.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 2, "Transform", matchers); + return new global::TUnit.Mocks.MockMethodCall(mock.Engine, 2, "Transform", matchers); } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt index 24e8949a51..67f4b50f62 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Mixed_Members.verified.txt @@ -47,10 +47,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IService_MockImpl(engine); engine.Raisable = impl; - var setup = new IService_MockSetup(engine); - var verify = new IService_MockVerify(engine); - var raise = new IService_MockRaise(impl); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, raise, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -139,242 +136,202 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IService_MockRaise : global::TUnit.Mocks.IMockRaise + public static class IService_MockMemberExtensions { - internal readonly IService_MockImpl Impl; - - internal IService_MockRaise(IService_MockImpl impl) => Impl = impl; - } - - public static class IService_MockRaiseExtensions - { - public static void StatusChanged(this global::TUnit.Mocks.IMockRaise raise, string e) - { - var r = (IService_MockRaise)raise; - r.Impl.Raise_StatusChanged(e); - } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class IService_MockSetup : global::TUnit.Mocks.IMockSetup - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IService_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IService_MockSetupExtensions - { - public static IService_GetAsync_M3_TypedSetup GetAsync(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg id) + public static IService_GetAsync_M3_MockCall GetAsync(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg id) { - var s = (IService_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { id.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(3, matchers, "GetAsync"); - s.Engine.AddSetup(methodSetup); - return new IService_GetAsync_M3_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IService_GetAsync_M3_MockCall(mock.Engine, 3, "GetAsync", matchers); } - public static IService_Process_M4_TypedSetup Process(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg data) + public static IService_Process_M4_MockCall Process(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg data) { - var s = (IService_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { data.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(4, matchers, "Process"); - s.Engine.AddSetup(methodSetup); - return new IService_Process_M4_TypedSetup(new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup)); + return new IService_Process_M4_MockCall(mock.Engine, 4, "Process", matchers); } - extension(global::TUnit.Mocks.IMockSetup setup) + extension(global::TUnit.Mocks.Mock mock) { - public global::TUnit.Mocks.Setup.PropertySetupAccessor Name - => new(((IService_MockSetup)setup).Engine, 0, 1, "Name", true, true); + public global::TUnit.Mocks.PropertyMockCall Name + => new(mock.Engine, 0, 1, "Name", true, true); + + public global::TUnit.Mocks.PropertyMockCall Count + => new(mock.Engine, 2, 0, "Count", true, false); + } - public global::TUnit.Mocks.Setup.PropertySetupAccessor Count - => new(((IService_MockSetup)setup).Engine, 2, 0, "Count", true, false); + public static void RaiseStatusChanged(this global::TUnit.Mocks.Mock mock, string e) + { + ((global::TUnit.Mocks.IRaisable)mock.Engine.Raisable!).RaiseEvent("StatusChanged", (object?)e); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IService_GetAsync_M3_TypedSetup : global::TUnit.Mocks.Setup.IMethodSetup, global::TUnit.Mocks.Setup.ISetupChain + public sealed class IService_GetAsync_M3_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; - - internal IService_GetAsync_M3_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Returns(string value) => _inner.Returns(value); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Returns(global::System.Func factory) => _inner.Returns(factory); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.ReturnsSequentially(params string[] values) => _inner.ReturnsSequentially(values); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Throws() => _inner.Throws(); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Throws(global::System.Exception exception) => _inner.Throws(exception); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Returns(global::System.Func factory) => _inner.Returns(factory); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.Raises(string eventName, object? args) => _inner.Raises(eventName, args); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.IMethodSetup.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + internal IService_GetAsync_M3_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } - global::TUnit.Mocks.Setup.IMethodSetup global::TUnit.Mocks.Setup.ISetupChain.Then() { _inner.Then(); return this; } - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.ISetupChain.Raises(string eventName, object? args) => _inner.Raises(eventName, args); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.ISetupChain.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); - global::TUnit.Mocks.Setup.ISetupChain global::TUnit.Mocks.Setup.ISetupChain.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IService_GetAsync_M3_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + public IService_GetAsync_M3_MockCall Returns(string value) { EnsureSetup().Returns(value); return this; } /// - public IService_GetAsync_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IService_GetAsync_M3_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IService_GetAsync_M3_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } + public IService_GetAsync_M3_MockCall ReturnsSequentially(params string[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IService_GetAsync_M3_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IService_GetAsync_M3_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IService_GetAsync_M3_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IService_GetAsync_M3_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IService_GetAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IService_GetAsync_M3_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IService_GetAsync_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IService_GetAsync_M3_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IService_GetAsync_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IService_GetAsync_M3_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IService_GetAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IService_GetAsync_M3_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IService_GetAsync_M3_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IService_GetAsync_M3_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IService_GetAsync_M3_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IService_GetAsync_M3_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IService_GetAsync_M3_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IService_GetAsync_M3_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IService_GetAsync_M3_TypedSetup Then() { _inner.Then(); return this; } + public IService_GetAsync_M3_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IService_GetAsync_M3_TypedSetup Returns(global::System.Func factory) + public IService_GetAsync_M3_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((int)args[0]!)); + EnsureSetup().Returns(args => factory((int)args[0]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IService_GetAsync_M3_TypedSetup Callback(global::System.Action callback) + public IService_GetAsync_M3_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((int)args[0]!)); + EnsureSetup().Callback(args => callback((int)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IService_GetAsync_M3_TypedSetup Throws(global::System.Func exceptionFactory) + public IService_GetAsync_M3_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((int)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((int)args[0]!)); return this; } /// Auto-raise the StatusChanged event when this method is called. - public IService_GetAsync_M3_TypedSetup RaisesStatusChanged(string e) { _inner.Raises("StatusChanged", (object?)e); return this; } + public IService_GetAsync_M3_MockCall RaisesStatusChanged(string e) { EnsureSetup().Raises("StatusChanged", (object?)e); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IService_Process_M4_TypedSetup : global::TUnit.Mocks.Setup.IVoidMethodSetup, global::TUnit.Mocks.Setup.IVoidSetupChain + public sealed class IService_Process_M4_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy _lazyBuilder; - internal IService_Process_M4_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; - - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws() => _inner.Throws(); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Exception exception) => _inner.Throws(exception); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Callback(global::System.Action callback) => _inner.Callback(callback); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.Raises(string eventName, object? args) => _inner.Raises(eventName, args); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidMethodSetup.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + internal IService_Process_M4_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(setup); + } + ); + _ = _lazyBuilder.Value; + } - global::TUnit.Mocks.Setup.IVoidMethodSetup global::TUnit.Mocks.Setup.IVoidSetupChain.Then() { _inner.Then(); return this; } - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.Raises(string eventName, object? args) => _inner.Raises(eventName, args); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value); - global::TUnit.Mocks.Setup.IVoidSetupChain global::TUnit.Mocks.Setup.IVoidSetupChain.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName); + private global::TUnit.Mocks.Setup.VoidMethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IService_Process_M4_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IService_Process_M4_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IService_Process_M4_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IService_Process_M4_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IService_Process_M4_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IService_Process_M4_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IService_Process_M4_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IService_Process_M4_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IService_Process_M4_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IService_Process_M4_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IService_Process_M4_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IService_Process_M4_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IService_Process_M4_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IService_Process_M4_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IService_Process_M4_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IService_Process_M4_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IService_Process_M4_TypedSetup Then() { _inner.Then(); return this; } + public IService_Process_M4_MockCall Then() { EnsureSetup().Then(); return this; } /// Execute a typed callback using the actual method parameters. - public IService_Process_M4_TypedSetup Callback(global::System.Action callback) + public IService_Process_M4_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!)); + EnsureSetup().Callback(args => callback((string)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IService_Process_M4_TypedSetup Throws(global::System.Func exceptionFactory) + public IService_Process_M4_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!)); return this; } /// Auto-raise the StatusChanged event when this method is called. - public IService_Process_M4_TypedSetup RaisesStatusChanged(string e) { _inner.Raises("StatusChanged", (object?)e); return this; } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class IService_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; + public IService_Process_M4_MockCall RaisesStatusChanged(string e) { EnsureSetup().Raises("StatusChanged", (object?)e); return this; } - internal IService_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IService_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification GetAsync(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg id) - { - var v = (IService_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { id.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 3, "GetAsync", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification Process(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg data) - { - var v = (IService_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { data.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 4, "Process", matchers); - } - - extension(global::TUnit.Mocks.IMockVerify verify) - { - public global::TUnit.Mocks.Verification.PropertyVerifyAccessor Name - => new(((IService_MockVerify)verify).Engine, 0, 1, "Name", true, true); - - public global::TUnit.Mocks.Verification.PropertyVerifyAccessor Count - => new(((IService_MockVerify)verify).Engine, 2, 0, "Count", true, false); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt index 8d5136761f..1c80691d99 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Out_Ref_Parameters.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IDictionary_MockImpl(engine); engine.Raisable = impl; - var setup = new IDictionary_MockSetup(engine); - var verify = new IDictionary_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -80,161 +78,192 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IDictionary_MockSetup : global::TUnit.Mocks.IMockSetup + public static class IDictionary_MockMemberExtensions { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IDictionary_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IDictionary_MockSetupExtensions - { - public static IDictionary_TryGetValue_M0_TypedSetup TryGetValue(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg key) + public static IDictionary_TryGetValue_M0_MockCall TryGetValue(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg key) { - var s = (IDictionary_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { key.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "TryGetValue"); - s.Engine.AddSetup(methodSetup); - return new IDictionary_TryGetValue_M0_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IDictionary_TryGetValue_M0_MockCall(mock.Engine, 0, "TryGetValue", matchers); } - public static IDictionary_Swap_M1_TypedSetup Swap(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) + public static IDictionary_Swap_M1_MockCall Swap(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) { - var s = (IDictionary_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { a.Matcher, b.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(1, matchers, "Swap"); - s.Engine.AddSetup(methodSetup); - return new IDictionary_Swap_M1_TypedSetup(new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup)); + return new IDictionary_Swap_M1_MockCall(mock.Engine, 1, "Swap", matchers); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IDictionary_TryGetValue_M0_TypedSetup + public sealed class IDictionary_TryGetValue_M0_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; + + internal IDictionary_TryGetValue_M0_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } - internal IDictionary_TryGetValue_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IDictionary_TryGetValue_M0_TypedSetup Returns(bool value) { _inner.Returns(value); return this; } + public IDictionary_TryGetValue_M0_MockCall Returns(bool value) { EnsureSetup().Returns(value); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IDictionary_TryGetValue_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup ReturnsSequentially(params bool[] values) { _inner.ReturnsSequentially(values); return this; } + public IDictionary_TryGetValue_M0_MockCall ReturnsSequentially(params bool[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IDictionary_TryGetValue_M0_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IDictionary_TryGetValue_M0_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IDictionary_TryGetValue_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IDictionary_TryGetValue_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IDictionary_TryGetValue_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IDictionary_TryGetValue_M0_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IDictionary_TryGetValue_M0_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public IDictionary_TryGetValue_M0_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IDictionary_TryGetValue_M0_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IDictionary_TryGetValue_M0_TypedSetup Then() { _inner.Then(); return this; } + public IDictionary_TryGetValue_M0_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IDictionary_TryGetValue_M0_TypedSetup Returns(global::System.Func factory) + public IDictionary_TryGetValue_M0_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((string)args[0]!)); + EnsureSetup().Returns(args => factory((string)args[0]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IDictionary_TryGetValue_M0_TypedSetup Callback(global::System.Action callback) + public IDictionary_TryGetValue_M0_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!)); + EnsureSetup().Callback(args => callback((string)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IDictionary_TryGetValue_M0_TypedSetup Throws(global::System.Func exceptionFactory) + public IDictionary_TryGetValue_M0_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!)); return this; } + + /// Sets the 'value' out parameter to the specified value when this setup matches. + public IDictionary_TryGetValue_M0_MockCall SetsOutValue(string value) { EnsureSetup().SetsOutParameter(1, value); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IDictionary_Swap_M1_TypedSetup + public sealed class IDictionary_Swap_M1_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.VoidMethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy _lazyBuilder; - internal IDictionary_Swap_M1_TypedSetup(global::TUnit.Mocks.Setup.VoidMethodSetupBuilder inner) => _inner = inner; + internal IDictionary_Swap_M1_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(setup); + } + ); + _ = _lazyBuilder.Value; + } + + private global::TUnit.Mocks.Setup.VoidMethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IDictionary_Swap_M1_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IDictionary_Swap_M1_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IDictionary_Swap_M1_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IDictionary_Swap_M1_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IDictionary_Swap_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IDictionary_Swap_M1_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IDictionary_Swap_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IDictionary_Swap_M1_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IDictionary_Swap_M1_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IDictionary_Swap_M1_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IDictionary_Swap_M1_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IDictionary_Swap_M1_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IDictionary_Swap_M1_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] + public IDictionary_Swap_M1_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IDictionary_Swap_M1_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IDictionary_Swap_M1_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IDictionary_Swap_M1_TypedSetup Then() { _inner.Then(); return this; } + public IDictionary_Swap_M1_MockCall Then() { EnsureSetup().Then(); return this; } /// Execute a typed callback using the actual method parameters. - public IDictionary_Swap_M1_TypedSetup Callback(global::System.Action callback) + public IDictionary_Swap_M1_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + EnsureSetup().Callback(args => callback((int)args[0]!, (int)args[1]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IDictionary_Swap_M1_TypedSetup Throws(global::System.Func exceptionFactory) + public IDictionary_Swap_M1_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + EnsureSetup().Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); return this; } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable -namespace TUnit.Mocks.Generated -{ - public sealed class IDictionary_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; + /// Sets the 'a' ref parameter to the specified value when this setup matches. + public IDictionary_Swap_M1_MockCall SetsRefA(int a) { EnsureSetup().SetsOutParameter(0, a); return this; } + /// Sets the 'b' ref parameter to the specified value when this setup matches. + public IDictionary_Swap_M1_MockCall SetsRefB(int b) { EnsureSetup().SetsOutParameter(1, b); return this; } - internal IDictionary_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IDictionary_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification TryGetValue(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg key) - { - var v = (IDictionary_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { key.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "TryGetValue", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification Swap(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) - { - var v = (IDictionary_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { a.Matcher, b.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 1, "Swap", matchers); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt index 382d2c901d..57c183c550 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Overloaded_Methods.verified.txt @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IFormatter_MockImpl(engine); engine.Raisable = impl; - var setup = new IFormatter_MockSetup(engine); - var verify = new IFormatter_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -77,320 +75,386 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IFormatter_MockSetup : global::TUnit.Mocks.IMockSetup + public static class IFormatter_MockMemberExtensions { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IFormatter_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IFormatter_MockSetupExtensions - { - public static IFormatter_Format_M0_TypedSetup Format(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg value) + public static IFormatter_Format_M0_MockCall Format(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg value) { - var s = (IFormatter_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { value.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "Format"); - s.Engine.AddSetup(methodSetup); - return new IFormatter_Format_M0_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IFormatter_Format_M0_MockCall(mock.Engine, 0, "Format", matchers); } - public static IFormatter_Format_M1_TypedSetup Format(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg value) + public static IFormatter_Format_M1_MockCall Format(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg value) { - var s = (IFormatter_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { value.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(1, matchers, "Format"); - s.Engine.AddSetup(methodSetup); - return new IFormatter_Format_M1_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IFormatter_Format_M1_MockCall(mock.Engine, 1, "Format", matchers); } - public static IFormatter_Format_M2_TypedSetup Format(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg template, global::TUnit.Mocks.Arguments.Arg arg1) + public static IFormatter_Format_M2_MockCall Format(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg template, global::TUnit.Mocks.Arguments.Arg arg1) { - var s = (IFormatter_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { template.Matcher, arg1.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(2, matchers, "Format"); - s.Engine.AddSetup(methodSetup); - return new IFormatter_Format_M2_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IFormatter_Format_M2_MockCall(mock.Engine, 2, "Format", matchers); } - public static IFormatter_Format_M3_TypedSetup Format(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg template, global::TUnit.Mocks.Arguments.Arg arg1, global::TUnit.Mocks.Arguments.Arg arg2) + public static IFormatter_Format_M3_MockCall Format(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg template, global::TUnit.Mocks.Arguments.Arg arg1, global::TUnit.Mocks.Arguments.Arg arg2) { - var s = (IFormatter_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { template.Matcher, arg1.Matcher, arg2.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(3, matchers, "Format"); - s.Engine.AddSetup(methodSetup); - return new IFormatter_Format_M3_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IFormatter_Format_M3_MockCall(mock.Engine, 3, "Format", matchers); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M0_TypedSetup + public sealed class IFormatter_Format_M0_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; + + internal IFormatter_Format_M0_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } - internal IFormatter_Format_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IFormatter_Format_M0_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + public IFormatter_Format_M0_MockCall Returns(string value) { EnsureSetup().Returns(value); return this; } /// - public IFormatter_Format_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M0_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } + public IFormatter_Format_M0_MockCall ReturnsSequentially(params string[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IFormatter_Format_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IFormatter_Format_M0_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IFormatter_Format_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IFormatter_Format_M0_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IFormatter_Format_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IFormatter_Format_M0_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IFormatter_Format_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IFormatter_Format_M0_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IFormatter_Format_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IFormatter_Format_M0_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IFormatter_Format_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IFormatter_Format_M0_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IFormatter_Format_M0_TypedSetup Then() { _inner.Then(); return this; } + public IFormatter_Format_M0_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IFormatter_Format_M0_TypedSetup Returns(global::System.Func factory) + public IFormatter_Format_M0_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((string)args[0]!)); + EnsureSetup().Returns(args => factory((string)args[0]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IFormatter_Format_M0_TypedSetup Callback(global::System.Action callback) + public IFormatter_Format_M0_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!)); + EnsureSetup().Callback(args => callback((string)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IFormatter_Format_M0_TypedSetup Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M0_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!)); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M1_TypedSetup + public sealed class IFormatter_Format_M1_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; - internal IFormatter_Format_M1_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + internal IFormatter_Format_M1_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } + + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IFormatter_Format_M1_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + public IFormatter_Format_M1_MockCall Returns(string value) { EnsureSetup().Returns(value); return this; } /// - public IFormatter_Format_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M1_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M1_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } + public IFormatter_Format_M1_MockCall ReturnsSequentially(params string[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IFormatter_Format_M1_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IFormatter_Format_M1_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IFormatter_Format_M1_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IFormatter_Format_M1_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IFormatter_Format_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M1_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M1_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M1_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M1_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IFormatter_Format_M1_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IFormatter_Format_M1_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IFormatter_Format_M1_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IFormatter_Format_M1_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IFormatter_Format_M1_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IFormatter_Format_M1_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IFormatter_Format_M1_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IFormatter_Format_M1_TypedSetup Then() { _inner.Then(); return this; } + public IFormatter_Format_M1_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IFormatter_Format_M1_TypedSetup Returns(global::System.Func factory) + public IFormatter_Format_M1_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((int)args[0]!)); + EnsureSetup().Returns(args => factory((int)args[0]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IFormatter_Format_M1_TypedSetup Callback(global::System.Action callback) + public IFormatter_Format_M1_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((int)args[0]!)); + EnsureSetup().Callback(args => callback((int)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IFormatter_Format_M1_TypedSetup Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M1_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((int)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((int)args[0]!)); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M2_TypedSetup + public sealed class IFormatter_Format_M2_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; + + internal IFormatter_Format_M2_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } - internal IFormatter_Format_M2_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IFormatter_Format_M2_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + public IFormatter_Format_M2_MockCall Returns(string value) { EnsureSetup().Returns(value); return this; } /// - public IFormatter_Format_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M2_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M2_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } + public IFormatter_Format_M2_MockCall ReturnsSequentially(params string[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IFormatter_Format_M2_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IFormatter_Format_M2_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IFormatter_Format_M2_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IFormatter_Format_M2_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IFormatter_Format_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M2_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M2_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M2_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M2_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M2_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M2_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IFormatter_Format_M2_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IFormatter_Format_M2_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IFormatter_Format_M2_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IFormatter_Format_M2_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IFormatter_Format_M2_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IFormatter_Format_M2_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IFormatter_Format_M2_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IFormatter_Format_M2_TypedSetup Then() { _inner.Then(); return this; } + public IFormatter_Format_M2_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IFormatter_Format_M2_TypedSetup Returns(global::System.Func factory) + public IFormatter_Format_M2_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((string)args[0]!, (string)args[1]!)); + EnsureSetup().Returns(args => factory((string)args[0]!, (string)args[1]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IFormatter_Format_M2_TypedSetup Callback(global::System.Action callback) + public IFormatter_Format_M2_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!, (string)args[1]!)); + EnsureSetup().Callback(args => callback((string)args[0]!, (string)args[1]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IFormatter_Format_M2_TypedSetup Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M2_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!)); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IFormatter_Format_M3_TypedSetup + public sealed class IFormatter_Format_M3_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; - internal IFormatter_Format_M3_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + internal IFormatter_Format_M3_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } + + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IFormatter_Format_M3_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + public IFormatter_Format_M3_MockCall Returns(string value) { EnsureSetup().Returns(value); return this; } /// - public IFormatter_Format_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M3_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M3_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } + public IFormatter_Format_M3_MockCall ReturnsSequentially(params string[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IFormatter_Format_M3_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IFormatter_Format_M3_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IFormatter_Format_M3_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IFormatter_Format_M3_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IFormatter_Format_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M3_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M3_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IFormatter_Format_M3_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IFormatter_Format_M3_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IFormatter_Format_M3_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IFormatter_Format_M3_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IFormatter_Format_M3_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IFormatter_Format_M3_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IFormatter_Format_M3_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IFormatter_Format_M3_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IFormatter_Format_M3_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IFormatter_Format_M3_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IFormatter_Format_M3_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IFormatter_Format_M3_TypedSetup Then() { _inner.Then(); return this; } + public IFormatter_Format_M3_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IFormatter_Format_M3_TypedSetup Returns(global::System.Func factory) + public IFormatter_Format_M3_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((string)args[0]!, (string)args[1]!, (string)args[2]!)); + EnsureSetup().Returns(args => factory((string)args[0]!, (string)args[1]!, (string)args[2]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IFormatter_Format_M3_TypedSetup Callback(global::System.Action callback) + public IFormatter_Format_M3_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!, (string)args[1]!, (string)args[2]!)); + EnsureSetup().Callback(args => callback((string)args[0]!, (string)args[1]!, (string)args[2]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IFormatter_Format_M3_TypedSetup Throws(global::System.Func exceptionFactory) + public IFormatter_Format_M3_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!, (string)args[2]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!, (string)args[1]!, (string)args[2]!)); return this; } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class IFormatter_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IFormatter_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IFormatter_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification Format(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg value) - { - var v = (IFormatter_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { value.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "Format", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification Format(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg value) - { - var v = (IFormatter_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { value.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 1, "Format", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification Format(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg template, global::TUnit.Mocks.Arguments.Arg arg1) - { - var v = (IFormatter_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { template.Matcher, arg1.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 2, "Format", matchers); - } - public static global::TUnit.Mocks.Verification.ICallVerification Format(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg template, global::TUnit.Mocks.Arguments.Arg arg1, global::TUnit.Mocks.Arguments.Arg arg2) - { - var v = (IFormatter_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { template.Matcher, arg1.Matcher, arg2.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 3, "Format", matchers); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Properties.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Properties.verified.txt index 9f8ab8245c..a40e899791 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Properties.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Interface_With_Properties.verified.txt @@ -1,4 +1,4 @@ -// +// #nullable enable namespace TUnit.Mocks.Generated @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IRepository_MockImpl(engine); engine.Raisable = impl; - var setup = new IRepository_MockSetup(engine); - var verify = new IRepository_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -73,56 +71,18 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IRepository_MockSetup : global::TUnit.Mocks.IMockSetup - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IRepository_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IRepository_MockSetupExtensions - { - extension(global::TUnit.Mocks.IMockSetup setup) - { - public global::TUnit.Mocks.Setup.PropertySetupAccessor Name - => new(((IRepository_MockSetup)setup).Engine, 0, 1, "Name", true, true); - - public global::TUnit.Mocks.Setup.PropertySetupAccessor Count - => new(((IRepository_MockSetup)setup).Engine, 2, 0, "Count", true, false); - - public global::TUnit.Mocks.Setup.PropertySetupAccessor IsOpen - => new(((IRepository_MockSetup)setup).Engine, 0, 4, "IsOpen", false, true); - } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class IRepository_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IRepository_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IRepository_MockVerifyExtensions + public static class IRepository_MockMemberExtensions { - extension(global::TUnit.Mocks.IMockVerify verify) + extension(global::TUnit.Mocks.Mock mock) { - public global::TUnit.Mocks.Verification.PropertyVerifyAccessor Name - => new(((IRepository_MockVerify)verify).Engine, 0, 1, "Name", true, true); + public global::TUnit.Mocks.PropertyMockCall Name + => new(mock.Engine, 0, 1, "Name", true, true); - public global::TUnit.Mocks.Verification.PropertyVerifyAccessor Count - => new(((IRepository_MockVerify)verify).Engine, 2, 0, "Count", true, false); + public global::TUnit.Mocks.PropertyMockCall Count + => new(mock.Engine, 2, 0, "Count", true, false); - public global::TUnit.Mocks.Verification.PropertyVerifyAccessor IsOpen - => new(((IRepository_MockVerify)verify).Engine, 0, 4, "IsOpen", false, true); + public global::TUnit.Mocks.PropertyMockCall IsOpen + => new(mock.Engine, 0, 4, "IsOpen", false, true); } } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt index ea0fcfae1b..e821bafd8c 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Multi_Method_Interface.verified.txt @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new ICalculator_MockImpl(engine); engine.Raisable = impl; - var setup = new ICalculator_MockSetup(engine); - var verify = new ICalculator_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -72,192 +70,202 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class ICalculator_MockSetup : global::TUnit.Mocks.IMockSetup + public static class ICalculator_MockMemberExtensions { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal ICalculator_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class ICalculator_MockSetupExtensions - { - public static ICalculator_Add_M0_TypedSetup Add(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) + public static ICalculator_Add_M0_MockCall Add(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) { - var s = (ICalculator_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { a.Matcher, b.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "Add"); - s.Engine.AddSetup(methodSetup); - return new ICalculator_Add_M0_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new ICalculator_Add_M0_MockCall(mock.Engine, 0, "Add", matchers); } - public static ICalculator_Subtract_M1_TypedSetup Subtract(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) + public static ICalculator_Subtract_M1_MockCall Subtract(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) { - var s = (ICalculator_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { a.Matcher, b.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(1, matchers, "Subtract"); - s.Engine.AddSetup(methodSetup); - return new ICalculator_Subtract_M1_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new ICalculator_Subtract_M1_MockCall(mock.Engine, 1, "Subtract", matchers); } - public static global::TUnit.Mocks.Setup.IVoidMethodSetup Reset(this global::TUnit.Mocks.IMockSetup setup) + public static global::TUnit.Mocks.VoidMockMethodCall Reset_(this global::TUnit.Mocks.Mock mock) { - var s = (ICalculator_MockSetup)setup; var matchers = global::System.Array.Empty(); - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(2, matchers, "Reset"); - s.Engine.AddSetup(methodSetup); - return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup); + return new global::TUnit.Mocks.VoidMockMethodCall(mock.Engine, 2, "Reset", matchers); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct ICalculator_Add_M0_TypedSetup + public sealed class ICalculator_Add_M0_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; - internal ICalculator_Add_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + internal ICalculator_Add_M0_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } + + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public ICalculator_Add_M0_TypedSetup Returns(int value) { _inner.Returns(value); return this; } + public ICalculator_Add_M0_MockCall Returns(int value) { EnsureSetup().Returns(value); return this; } /// - public ICalculator_Add_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public ICalculator_Add_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public ICalculator_Add_M0_TypedSetup ReturnsSequentially(params int[] values) { _inner.ReturnsSequentially(values); return this; } + public ICalculator_Add_M0_MockCall ReturnsSequentially(params int[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public ICalculator_Add_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public ICalculator_Add_M0_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public ICalculator_Add_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public ICalculator_Add_M0_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public ICalculator_Add_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public ICalculator_Add_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public ICalculator_Add_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public ICalculator_Add_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public ICalculator_Add_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public ICalculator_Add_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public ICalculator_Add_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public ICalculator_Add_M0_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public ICalculator_Add_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public ICalculator_Add_M0_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public ICalculator_Add_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public ICalculator_Add_M0_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public ICalculator_Add_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public ICalculator_Add_M0_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public ICalculator_Add_M0_TypedSetup Then() { _inner.Then(); return this; } + public ICalculator_Add_M0_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public ICalculator_Add_M0_TypedSetup Returns(global::System.Func factory) + public ICalculator_Add_M0_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((int)args[0]!, (int)args[1]!)); + EnsureSetup().Returns(args => factory((int)args[0]!, (int)args[1]!)); return this; } /// Execute a typed callback using the actual method parameters. - public ICalculator_Add_M0_TypedSetup Callback(global::System.Action callback) + public ICalculator_Add_M0_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + EnsureSetup().Callback(args => callback((int)args[0]!, (int)args[1]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public ICalculator_Add_M0_TypedSetup Throws(global::System.Func exceptionFactory) + public ICalculator_Add_M0_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + EnsureSetup().Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); return this; } + + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct ICalculator_Subtract_M1_TypedSetup + public sealed class ICalculator_Subtract_M1_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; - internal ICalculator_Subtract_M1_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + internal ICalculator_Subtract_M1_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } + + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public ICalculator_Subtract_M1_TypedSetup Returns(int value) { _inner.Returns(value); return this; } + public ICalculator_Subtract_M1_MockCall Returns(int value) { EnsureSetup().Returns(value); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public ICalculator_Subtract_M1_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public ICalculator_Subtract_M1_TypedSetup ReturnsSequentially(params int[] values) { _inner.ReturnsSequentially(values); return this; } + public ICalculator_Subtract_M1_MockCall ReturnsSequentially(params int[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public ICalculator_Subtract_M1_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public ICalculator_Subtract_M1_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public ICalculator_Subtract_M1_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public ICalculator_Subtract_M1_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public ICalculator_Subtract_M1_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public ICalculator_Subtract_M1_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public ICalculator_Subtract_M1_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public ICalculator_Subtract_M1_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public ICalculator_Subtract_M1_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public ICalculator_Subtract_M1_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public ICalculator_Subtract_M1_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public ICalculator_Subtract_M1_TypedSetup Then() { _inner.Then(); return this; } + public ICalculator_Subtract_M1_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public ICalculator_Subtract_M1_TypedSetup Returns(global::System.Func factory) + public ICalculator_Subtract_M1_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((int)args[0]!, (int)args[1]!)); + EnsureSetup().Returns(args => factory((int)args[0]!, (int)args[1]!)); return this; } /// Execute a typed callback using the actual method parameters. - public ICalculator_Subtract_M1_TypedSetup Callback(global::System.Action callback) + public ICalculator_Subtract_M1_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((int)args[0]!, (int)args[1]!)); + EnsureSetup().Callback(args => callback((int)args[0]!, (int)args[1]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public ICalculator_Subtract_M1_TypedSetup Throws(global::System.Func exceptionFactory) + public ICalculator_Subtract_M1_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); + EnsureSetup().Throws(args => exceptionFactory((int)args[0]!, (int)args[1]!)); return this; } - } -} - - -// ===== FILE SEPARATOR ===== -// -#nullable enable - -namespace TUnit.Mocks.Generated -{ - public sealed class ICalculator_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal ICalculator_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class ICalculator_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification Add(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) - { - var v = (ICalculator_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { a.Matcher, b.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "Add", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification Subtract(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg a, global::TUnit.Mocks.Arguments.Arg b) - { - var v = (ICalculator_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { a.Matcher, b.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 1, "Subtract", matchers); - } - - public static global::TUnit.Mocks.Verification.ICallVerification Reset(this global::TUnit.Mocks.IMockVerify verify) - { - var v = (ICalculator_MockVerify)verify; - var matchers = global::System.Array.Empty(); - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 2, "Reset", matchers); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt index 6f5096a4c6..cfb21aec13 100644 --- a/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt +++ b/TUnit.Mocks.SourceGenerator.Tests/Snapshots/Simple_Interface_With_One_Method.verified.txt @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated var engine = new global::TUnit.Mocks.MockEngine(behavior); var impl = new IGreeter_MockImpl(engine); engine.Raisable = impl; - var setup = new IGreeter_MockSetup(engine); - var verify = new IGreeter_MockVerify(engine); - var mock = new global::TUnit.Mocks.Mock(impl, setup, verify, engine); + var mock = new global::TUnit.Mocks.Mock(impl, engine); return mock; } } @@ -62,104 +60,101 @@ namespace TUnit.Mocks.Generated namespace TUnit.Mocks.Generated { - public sealed class IGreeter_MockSetup : global::TUnit.Mocks.IMockSetup + public static class IGreeter_MockMemberExtensions { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IGreeter_MockSetup(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IGreeter_MockSetupExtensions - { - public static IGreeter_Greet_M0_TypedSetup Greet(this global::TUnit.Mocks.IMockSetup setup, global::TUnit.Mocks.Arguments.Arg name) + public static IGreeter_Greet_M0_MockCall Greet(this global::TUnit.Mocks.Mock mock, global::TUnit.Mocks.Arguments.Arg name) { - var s = (IGreeter_MockSetup)setup; var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { name.Matcher }; - var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(0, matchers, "Greet"); - s.Engine.AddSetup(methodSetup); - return new IGreeter_Greet_M0_TypedSetup(new global::TUnit.Mocks.Setup.MethodSetupBuilder(methodSetup)); + return new IGreeter_Greet_M0_MockCall(mock.Engine, 0, "Greet", matchers); } } [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)] - public readonly struct IGreeter_Greet_M0_TypedSetup + public sealed class IGreeter_Greet_M0_MockCall : global::TUnit.Mocks.Verification.ICallVerification { - private readonly global::TUnit.Mocks.Setup.MethodSetupBuilder _inner; + private readonly global::TUnit.Mocks.IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers; + private readonly global::System.Lazy> _lazyBuilder; + + internal IGreeter_Greet_M0_MockCall(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new global::System.Lazy>(() => + { + var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new global::TUnit.Mocks.Setup.MethodSetupBuilder(setup); + } + ); + } - internal IGreeter_Greet_M0_TypedSetup(global::TUnit.Mocks.Setup.MethodSetupBuilder inner) => _inner = inner; + private global::TUnit.Mocks.Setup.MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; /// - public IGreeter_Greet_M0_TypedSetup Returns(string value) { _inner.Returns(value); return this; } + public IGreeter_Greet_M0_MockCall Returns(string value) { EnsureSetup().Returns(value); return this; } /// - public IGreeter_Greet_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IGreeter_Greet_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IGreeter_Greet_M0_TypedSetup ReturnsSequentially(params string[] values) { _inner.ReturnsSequentially(values); return this; } + public IGreeter_Greet_M0_MockCall ReturnsSequentially(params string[] values) { EnsureSetup().ReturnsSequentially(values); return this; } /// - public IGreeter_Greet_M0_TypedSetup Throws() where TException : global::System.Exception, new() { _inner.Throws(); return this; } + public IGreeter_Greet_M0_MockCall Throws() where TException : global::System.Exception, new() { EnsureSetup().Throws(); return this; } /// - public IGreeter_Greet_M0_TypedSetup Throws(global::System.Exception exception) { _inner.Throws(exception); return this; } + public IGreeter_Greet_M0_MockCall Throws(global::System.Exception exception) { EnsureSetup().Throws(exception); return this; } /// - public IGreeter_Greet_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IGreeter_Greet_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IGreeter_Greet_M0_TypedSetup Callback(global::System.Action callback) { _inner.Callback(callback); return this; } + public IGreeter_Greet_M0_MockCall Callback(global::System.Action callback) { EnsureSetup().Callback(callback); return this; } /// - public IGreeter_Greet_M0_TypedSetup Returns(global::System.Func factory) { _inner.Returns(factory); return this; } + public IGreeter_Greet_M0_MockCall Returns(global::System.Func factory) { EnsureSetup().Returns(factory); return this; } /// - public IGreeter_Greet_M0_TypedSetup Throws(global::System.Func exceptionFactory) { _inner.Throws(exceptionFactory); return this; } + public IGreeter_Greet_M0_MockCall Throws(global::System.Func exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; } /// - public IGreeter_Greet_M0_TypedSetup Raises(string eventName, object? args = null) { _inner.Raises(eventName, args); return this; } + public IGreeter_Greet_M0_MockCall Raises(string eventName, object? args = null) { EnsureSetup().Raises(eventName, args); return this; } /// - public IGreeter_Greet_M0_TypedSetup SetsOutParameter(int paramIndex, object? value) { _inner.SetsOutParameter(paramIndex, value); return this; } + public IGreeter_Greet_M0_MockCall SetsOutParameter(int paramIndex, object? value) { EnsureSetup().SetsOutParameter(paramIndex, value); return this; } /// - public IGreeter_Greet_M0_TypedSetup TransitionsTo(string stateName) { _inner.TransitionsTo(stateName); return this; } + public IGreeter_Greet_M0_MockCall TransitionsTo(string stateName) { EnsureSetup().TransitionsTo(stateName); return this; } /// - public IGreeter_Greet_M0_TypedSetup Then() { _inner.Then(); return this; } + public IGreeter_Greet_M0_MockCall Then() { EnsureSetup().Then(); return this; } /// Configure a typed computed return value using the actual method parameters. - public IGreeter_Greet_M0_TypedSetup Returns(global::System.Func factory) + public IGreeter_Greet_M0_MockCall Returns(global::System.Func factory) { - _inner.Returns(args => factory((string)args[0]!)); + EnsureSetup().Returns(args => factory((string)args[0]!)); return this; } /// Execute a typed callback using the actual method parameters. - public IGreeter_Greet_M0_TypedSetup Callback(global::System.Action callback) + public IGreeter_Greet_M0_MockCall Callback(global::System.Action callback) { - _inner.Callback(args => callback((string)args[0]!)); + EnsureSetup().Callback(args => callback((string)args[0]!)); return this; } /// Configure a typed computed exception using the actual method parameters. - public IGreeter_Greet_M0_TypedSetup Throws(global::System.Func exceptionFactory) + public IGreeter_Greet_M0_MockCall Throws(global::System.Func exceptionFactory) { - _inner.Throws(args => exceptionFactory((string)args[0]!)); + EnsureSetup().Throws(args => exceptionFactory((string)args[0]!)); return this; } - } -} - - -// ===== FILE SEPARATOR ===== - -// -#nullable enable -namespace TUnit.Mocks.Generated -{ - public sealed class IGreeter_MockVerify : global::TUnit.Mocks.IMockVerify - { - internal readonly global::TUnit.Mocks.MockEngine Engine; - - internal IGreeter_MockVerify(global::TUnit.Mocks.MockEngine engine) => Engine = engine; - } - - public static class IGreeter_MockVerifyExtensions - { - public static global::TUnit.Mocks.Verification.ICallVerification Greet(this global::TUnit.Mocks.IMockVerify verify, global::TUnit.Mocks.Arguments.Arg name) - { - var v = (IGreeter_MockVerify)verify; - var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { name.Matcher }; - return new global::TUnit.Mocks.Verification.CallVerificationBuilder(v.Engine, 0, "Greet", matchers); - } + // ICallVerification + /// + public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + /// + public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + /// + public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + /// + public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + /// + public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + /// + public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); } } diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockDelegateFactoryBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockDelegateFactoryBuilder.cs index a29e392680..31dd19774e 100644 --- a/TUnit.Mocks.SourceGenerator/Builders/MockDelegateFactoryBuilder.cs +++ b/TUnit.Mocks.SourceGenerator/Builders/MockDelegateFactoryBuilder.cs @@ -72,9 +72,7 @@ public static string Build(MockTypeModel model) writer.AppendLine("};"); } - writer.AppendLine($"var setup = new {safeName}_MockSetup(engine);"); - writer.AppendLine($"var verify = new {safeName}_MockVerify(engine);"); - writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(del, setup, verify, engine);"); + writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(del, engine);"); writer.AppendLine("return mock;"); } } diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockFactoryBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockFactoryBuilder.cs index dfdc2cdb26..4e57f9bec4 100644 --- a/TUnit.Mocks.SourceGenerator/Builders/MockFactoryBuilder.cs +++ b/TUnit.Mocks.SourceGenerator/Builders/MockFactoryBuilder.cs @@ -61,27 +61,10 @@ private static void BuildInterfaceFactory(CodeWriter writer, MockTypeModel model using (writer.Block($"private static global::TUnit.Mocks.Mock<{model.FullyQualifiedName}> Create(global::TUnit.Mocks.MockBehavior behavior)")) { - // For multi-interface mocks: impl uses composite name, setup/verify use primary name - var primarySafeName = MockImplBuilder.GetSafeName(model.FullyQualifiedName); - writer.AppendLine($"var engine = new global::TUnit.Mocks.MockEngine<{model.FullyQualifiedName}>(behavior);"); writer.AppendLine($"var impl = new {safeName}_MockImpl(engine);"); writer.AppendLine("engine.Raisable = impl;"); - writer.AppendLine($"var setup = new {primarySafeName}_MockSetup(engine);"); - writer.AppendLine($"var verify = new {primarySafeName}_MockVerify(engine);"); - - // Events: check primary type events (from the single-type model) - // For multi-interface, we only use primary type's raise surface - if (model.Events.Length > 0 && model.AdditionalInterfaceNames.Length == 0) - { - writer.AppendLine($"var raise = new {primarySafeName}_MockRaise(impl);"); - writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, setup, verify, raise, engine);"); - } - else - { - writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, setup, verify, engine);"); - } - + writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, engine);"); writer.AppendLine("return mock;"); } } @@ -104,18 +87,7 @@ private static void BuildWrapFactory(CodeWriter writer, MockTypeModel model, str writer.AppendLine("engine.IsWrapMock = true;"); writer.AppendLine($"var impl = new {safeName}_WrapMockImpl(engine, instance);"); writer.AppendLine("engine.Raisable = impl;"); - writer.AppendLine($"var setup = new {safeName}_MockSetup(engine);"); - writer.AppendLine($"var verify = new {safeName}_MockVerify(engine);"); - if (model.Events.Length > 0) - { - writer.AppendLine($"var raise = new {safeName}_MockRaise(impl);"); - writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, setup, verify, raise, engine);"); - } - else - { - writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, setup, verify, engine);"); - } - + writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, engine);"); writer.AppendLine("return mock;"); } } @@ -140,18 +112,7 @@ private static void BuildPartialFactory(CodeWriter writer, MockTypeModel model, GenerateConstructorDispatch(writer, model, safeName); writer.AppendLine("engine.Raisable = impl;"); - writer.AppendLine($"var setup = new {safeName}_MockSetup(engine);"); - writer.AppendLine($"var verify = new {safeName}_MockVerify(engine);"); - if (model.Events.Length > 0) - { - writer.AppendLine($"var raise = new {safeName}_MockRaise(impl);"); - writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, setup, verify, raise, engine);"); - } - else - { - writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, setup, verify, engine);"); - } - + writer.AppendLine($"var mock = new global::TUnit.Mocks.Mock<{model.FullyQualifiedName}>(impl, engine);"); writer.AppendLine("return mock;"); } } diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockMembersBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockMembersBuilder.cs new file mode 100644 index 0000000000..7d0c07328b --- /dev/null +++ b/TUnit.Mocks.SourceGenerator/Builders/MockMembersBuilder.cs @@ -0,0 +1,599 @@ +using System.Collections.Generic; +using System.Linq; +using TUnit.Mocks.SourceGenerator.Models; + +namespace TUnit.Mocks.SourceGenerator.Builders; + +/// +/// Generates a single _MockMembers.g.cs file per mocked type, containing: +/// 1. Extension methods on Mock<T> for each method +/// 2. Extension properties on Mock<T> for each property (C# 14 extension blocks) +/// 3. Unified sealed classes per qualifying method (with BOTH setup and verify methods) +/// +internal static class MockMembersBuilder +{ + private const int MaxTypedParams = 8; + + private static readonly HashSet MockMemberNames = new(System.StringComparer.Ordinal) + { + "Object", "Engine", "Behavior", "Invocations", "DefaultValueProvider", + "SetupAllProperties", "Reset", "VerifyAll", "VerifyNoOtherCalls", + "GetAutoMock", "GetDiagnostics", "SetState", "InState", + "GetHashCode", "GetType", "ToString", "Equals" + }; + + public static string Build(MockTypeModel model) + { + var writer = new CodeWriter(); + var safeName = MockImplBuilder.GetSafeName(model.FullyQualifiedName); + var hasEvents = model.Events.Length > 0; + + writer.AppendLine("// "); + writer.AppendLine("#nullable enable"); + writer.AppendLine(); + + using (writer.Block("namespace TUnit.Mocks.Generated")) + { + // Extension methods class + using (writer.Block($"public static class {safeName}_MockMemberExtensions")) + { + bool firstMember = true; + + // Methods + foreach (var method in model.Methods) + { + if (!firstMember) writer.AppendLine(); + firstMember = false; + GenerateMemberMethod(writer, method, model, safeName); + } + + // Properties -- extension properties via C# 14 extension blocks + var memberProps = model.Properties + .Where(p => !p.IsIndexer && (p.HasGetter || p.HasSetter)) + .ToList(); + if (memberProps.Count > 0) + { + if (!firstMember) writer.AppendLine(); + firstMember = false; + GeneratePropertyExtensionBlock(writer, memberProps, model, safeName); + } + + // Raise extension methods for events + if (model.Events.Length > 0) + { + if (!firstMember) writer.AppendLine(); + firstMember = false; + GenerateRaiseExtensionMethods(writer, model); + } + } + + // Generate unified sealed classes for qualifying methods + foreach (var method in model.Methods) + { + if (!ShouldGenerateTypedWrapper(method, hasEvents)) continue; + writer.AppendLine(); + GenerateUnifiedSealedClass(writer, method, safeName, model.Events); + } + } + + return writer.ToString(); + } + + private static bool ShouldGenerateTypedWrapper(MockMemberModel method, bool hasEvents) + { + if (method.IsGenericMethod) return false; + + var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); + if (nonOutParams.Count == 0) + { + var hasOutRefParams = method.Parameters.Any(p => p.Direction == ParameterDirection.Out || p.Direction == ParameterDirection.Ref); + return hasEvents || hasOutRefParams; + } + return nonOutParams.Count <= MaxTypedParams; + } + + private static string GetWrapperName(string safeName, MockMemberModel method) + => $"{safeName}_{method.Name}_M{method.MemberId}_MockCall"; + + private static string GetSafeMemberName(string name) + => MockMemberNames.Contains(name) ? name + "_" : name; + + private static void GenerateUnifiedSealedClass(CodeWriter writer, MockMemberModel method, string safeName, + EquatableArray events) + { + var setupReturnType = method.IsAsync && !method.IsVoid + ? method.UnwrappedReturnType + : method.ReturnType; + + var wrapperName = GetWrapperName(safeName, method); + var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); + + if (method.IsVoid) + { + GenerateVoidUnifiedClass(writer, wrapperName, nonOutParams, events, method.Parameters); + } + else + { + GenerateReturnUnifiedClass(writer, wrapperName, nonOutParams, setupReturnType, events, method.Parameters); + } + } + + private static void GenerateReturnUnifiedClass(CodeWriter writer, string wrapperName, + List nonOutParams, string returnType, EquatableArray events, + EquatableArray allParameters) + { + var builderType = $"global::TUnit.Mocks.Setup.MethodSetupBuilder<{returnType}>"; + var hasOutRef = allParameters.Any(p => p.Direction == ParameterDirection.Out || p.Direction == ParameterDirection.Ref); + + writer.AppendLine("[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); + using (writer.Block($"public sealed class {wrapperName} : global::TUnit.Mocks.Verification.ICallVerification")) + { + // Fields + writer.AppendLine("private readonly global::TUnit.Mocks.IMockEngineAccess _engine;"); + writer.AppendLine("private readonly int _memberId;"); + writer.AppendLine("private readonly string _memberName;"); + writer.AppendLine("private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers;"); + writer.AppendLine($"private readonly global::System.Lazy<{builderType}> _lazyBuilder;"); + writer.AppendLine(); + + // Constructor — lazy registration via Lazy for thread safety + writer.AppendLine($"internal {wrapperName}(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers)"); + using (writer.Block()) + { + writer.AppendLine("_engine = engine;"); + writer.AppendLine("_memberId = memberId;"); + writer.AppendLine("_memberName = memberName;"); + writer.AppendLine("_matchers = matchers;"); + using (writer.Block($"_lazyBuilder = new global::System.Lazy<{builderType}>(() =>")) + { + writer.AppendLine("var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName);"); + writer.AppendLine("_engine.AddSetup(setup);"); + writer.AppendLine($"return new {builderType}(setup);"); + } + writer.AppendLine(");"); + } + + writer.AppendLine(); + + // EnsureSetup method + writer.AppendLine($"private {builderType} EnsureSetup() => _lazyBuilder.Value;"); + + writer.AppendLine(); + + // Public self-returning setup methods + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Returns({returnType} value) {{ EnsureSetup().Returns(value); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Returns(global::System.Func<{returnType}> factory) {{ EnsureSetup().Returns(factory); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} ReturnsSequentially(params {returnType}[] values) {{ EnsureSetup().ReturnsSequentially(values); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Throws() where TException : global::System.Exception, new() {{ EnsureSetup().Throws(); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Throws(global::System.Exception exception) {{ EnsureSetup().Throws(exception); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ EnsureSetup().Callback(callback); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ EnsureSetup().Callback(callback); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Returns(global::System.Func factory) {{ EnsureSetup().Returns(factory); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Throws(global::System.Func exceptionFactory) {{ EnsureSetup().Throws(exceptionFactory); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Raises(string eventName, object? args = null) {{ EnsureSetup().Raises(eventName, args); return this; }}"); + writer.AppendLine($"/// "); + if (hasOutRef) + writer.AppendLine("[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); + writer.AppendLine($"public {wrapperName} SetsOutParameter(int paramIndex, object? value) {{ EnsureSetup().SetsOutParameter(paramIndex, value); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} TransitionsTo(string stateName) {{ EnsureSetup().TransitionsTo(stateName); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Then() {{ EnsureSetup().Then(); return this; }}"); + + // Typed parameter overloads (only for methods with typed params) + if (nonOutParams.Count >= 1) + { + writer.AppendLine(); + GenerateTypedReturnsOverload(writer, nonOutParams, returnType, wrapperName); + writer.AppendLine(); + GenerateTypedCallbackOverload(writer, nonOutParams, wrapperName); + writer.AppendLine(); + GenerateTypedThrowsOverload(writer, nonOutParams, wrapperName); + } + + // Typed out/ref parameter setters + if (hasOutRef) + { + writer.AppendLine(); + GenerateTypedOutRefMethods(writer, allParameters, wrapperName); + } + + // Typed event raises + if (events.Length > 0) + { + writer.AppendLine(); + GenerateTypedEventRaises(writer, events, wrapperName); + } + + // Verify methods (ICallVerification implementation) + writer.AppendLine(); + writer.AppendLine("// ICallVerification"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled();"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times);"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message);"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message);"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled();"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message);"); + } + } + + private static void GenerateVoidUnifiedClass(CodeWriter writer, string wrapperName, + List nonOutParams, EquatableArray events, + EquatableArray allParameters) + { + var builderType = "global::TUnit.Mocks.Setup.VoidMethodSetupBuilder"; + var hasOutRef = allParameters.Any(p => p.Direction == ParameterDirection.Out || p.Direction == ParameterDirection.Ref); + + writer.AppendLine($"[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); + using (writer.Block($"public sealed class {wrapperName} : global::TUnit.Mocks.Verification.ICallVerification")) + { + // Fields + writer.AppendLine("private readonly global::TUnit.Mocks.IMockEngineAccess _engine;"); + writer.AppendLine("private readonly int _memberId;"); + writer.AppendLine("private readonly string _memberName;"); + writer.AppendLine("private readonly global::TUnit.Mocks.Arguments.IArgumentMatcher[] _matchers;"); + writer.AppendLine($"private readonly global::System.Lazy<{builderType}> _lazyBuilder;"); + writer.AppendLine(); + + // Constructor — Lazy for thread safety, eagerly materialized because void methods + // are commonly used without chaining (e.g., mock.Log(Arg.Any()) in strict mode). + writer.AppendLine($"internal {wrapperName}(global::TUnit.Mocks.IMockEngineAccess engine, int memberId, string memberName, global::TUnit.Mocks.Arguments.IArgumentMatcher[] matchers)"); + using (writer.Block()) + { + writer.AppendLine("_engine = engine;"); + writer.AppendLine("_memberId = memberId;"); + writer.AppendLine("_memberName = memberName;"); + writer.AppendLine("_matchers = matchers;"); + using (writer.Block($"_lazyBuilder = new global::System.Lazy<{builderType}>(() =>")) + { + writer.AppendLine("var setup = new global::TUnit.Mocks.Setup.MethodSetup(_memberId, _matchers, _memberName);"); + writer.AppendLine("_engine.AddSetup(setup);"); + writer.AppendLine($"return new {builderType}(setup);"); + } + writer.AppendLine(");"); + writer.AppendLine("_ = _lazyBuilder.Value;"); + } + + writer.AppendLine(); + + // EnsureSetup method + writer.AppendLine($"private {builderType} EnsureSetup() => _lazyBuilder.Value;"); + + writer.AppendLine(); + + // Public self-returning setup methods + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Throws() where TException : global::System.Exception, new() {{ EnsureSetup().Throws(); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Throws(global::System.Exception exception) {{ EnsureSetup().Throws(exception); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ EnsureSetup().Callback(callback); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ EnsureSetup().Callback(callback); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Throws(global::System.Func exceptionFactory) {{ EnsureSetup().Throws(exceptionFactory); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Raises(string eventName, object? args = null) {{ EnsureSetup().Raises(eventName, args); return this; }}"); + writer.AppendLine($"/// "); + if (hasOutRef) + writer.AppendLine("[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); + writer.AppendLine($"public {wrapperName} SetsOutParameter(int paramIndex, object? value) {{ EnsureSetup().SetsOutParameter(paramIndex, value); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} TransitionsTo(string stateName) {{ EnsureSetup().TransitionsTo(stateName); return this; }}"); + writer.AppendLine($"/// "); + writer.AppendLine($"public {wrapperName} Then() {{ EnsureSetup().Then(); return this; }}"); + + // Typed parameter overloads (only for methods with typed params) + if (nonOutParams.Count >= 1) + { + writer.AppendLine(); + GenerateTypedCallbackOverload(writer, nonOutParams, wrapperName); + writer.AppendLine(); + GenerateTypedThrowsOverload(writer, nonOutParams, wrapperName); + } + + // Typed out/ref parameter setters + if (hasOutRef) + { + writer.AppendLine(); + GenerateTypedOutRefMethods(writer, allParameters, wrapperName); + } + + // Typed event raises + if (events.Length > 0) + { + writer.AppendLine(); + GenerateTypedEventRaises(writer, events, wrapperName); + } + + // Verify methods (ICallVerification implementation) + writer.AppendLine(); + writer.AppendLine("// ICallVerification"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled();"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times);"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message);"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message);"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled();"); + writer.AppendLine("/// "); + writer.AppendLine("public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message);"); + } + } + + private static void GenerateTypedReturnsOverload(CodeWriter writer, List nonOutParams, + string returnType, string wrapperName) + { + var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); + var funcType = $"global::System.Func<{typeList}, {returnType}>"; + var castArgs = BuildCastArgs(nonOutParams); + + writer.AppendLine("/// Configure a typed computed return value using the actual method parameters."); + using (writer.Block($"public {wrapperName} Returns({funcType} factory)")) + { + writer.AppendLine($"EnsureSetup().Returns(args => factory({castArgs}));"); + writer.AppendLine("return this;"); + } + } + + private static void GenerateTypedCallbackOverload(CodeWriter writer, List nonOutParams, + string wrapperName) + { + var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); + var actionType = $"global::System.Action<{typeList}>"; + var castArgs = BuildCastArgs(nonOutParams); + + writer.AppendLine("/// Execute a typed callback using the actual method parameters."); + using (writer.Block($"public {wrapperName} Callback({actionType} callback)")) + { + writer.AppendLine($"EnsureSetup().Callback(args => callback({castArgs}));"); + writer.AppendLine("return this;"); + } + } + + private static void GenerateTypedThrowsOverload(CodeWriter writer, List nonOutParams, + string wrapperName) + { + var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); + var funcType = $"global::System.Func<{typeList}, global::System.Exception>"; + var castArgs = BuildCastArgs(nonOutParams); + + writer.AppendLine("/// Configure a typed computed exception using the actual method parameters."); + using (writer.Block($"public {wrapperName} Throws({funcType} exceptionFactory)")) + { + writer.AppendLine($"EnsureSetup().Throws(args => exceptionFactory({castArgs}));"); + writer.AppendLine("return this;"); + } + } + + private static void GenerateTypedEventRaises(CodeWriter writer, EquatableArray events, + string wrapperName) + { + bool first = true; + foreach (var evt in events) + { + if (!first) writer.AppendLine(); + first = false; + + var paramList = evt.RaiseParameterList.Length == 0 + ? "" + : string.Join(", ", evt.RaiseParameterList.Select(p => $"{p.FullyQualifiedType} {p.Name}")); + + string argsExpr; + if (evt.RaiseParameterList.Length == 0) + { + argsExpr = ""; + } + else if (evt.RaiseParameterList.Length == 1) + { + argsExpr = $", (object?){evt.RaiseParameterList[0].Name}"; + } + else + { + var argNames = string.Join(", ", evt.RaiseParameterList.Select(p => p.Name)); + argsExpr = $", (object?)new object?[] {{ {argNames} }}"; + } + + writer.AppendLine($"/// Auto-raise the {evt.Name} event when this method is called."); + writer.AppendLine($"public {wrapperName} Raises{evt.Name}({paramList}) {{ EnsureSetup().Raises(\"{evt.Name}\"{argsExpr}); return this; }}"); + } + } + + private static void GenerateTypedOutRefMethods(CodeWriter writer, EquatableArray allParameters, string wrapperName) + { + for (int i = 0; i < allParameters.Length; i++) + { + var param = allParameters[i]; + if (param.Direction != ParameterDirection.Out && param.Direction != ParameterDirection.Ref) + continue; + + var prefix = param.Direction == ParameterDirection.Out ? "SetsOut" : "SetsRef"; + var methodName = prefix + ToPascalCase(param.Name); + var dirLabel = param.Direction == ParameterDirection.Out ? "out" : "ref"; + + writer.AppendLine($"/// Sets the '{param.Name}' {dirLabel} parameter to the specified value when this setup matches."); + writer.AppendLine($"public {wrapperName} {methodName}({param.FullyQualifiedType} {param.Name}) {{ EnsureSetup().SetsOutParameter({i}, {param.Name}); return this; }}"); + } + } + + private static string ToPascalCase(string name) + => string.IsNullOrEmpty(name) ? name : char.ToUpperInvariant(name[0]) + name[1..]; + + private static string BuildCastArgs(List nonOutParams) + { + return string.Join(", ", nonOutParams.Select((p, i) => + $"({p.FullyQualifiedType})args[{i}]!")); + } + + private static void GenerateMemberMethod(CodeWriter writer, MockMemberModel method, MockTypeModel model, string safeName) + { + // For async methods (Task/ValueTask), unwrap the return type so users write .Returns(5) not .Returns(Task.FromResult(5)) + // For void-async methods (Task/ValueTask), IsVoid is already true + var setupReturnType = method.IsAsync && !method.IsVoid + ? method.UnwrappedReturnType + : method.ReturnType; + + var hasEvents = model.Events.Length > 0; + var useTypedWrapper = ShouldGenerateTypedWrapper(method, hasEvents); + string returnType; + + if (useTypedWrapper) + { + returnType = GetWrapperName(safeName, method); + } + else if (method.IsVoid) + { + returnType = "global::TUnit.Mocks.VoidMockMethodCall"; + } + else + { + returnType = $"global::TUnit.Mocks.MockMethodCall<{setupReturnType}>"; + } + + var paramList = GetArgParameterList(method); + var typeParams = GetTypeParameterList(method); + var constraints = GetConstraintClauses(method); + + var safeMemberName = GetSafeMemberName(method.Name); + var extensionParam = $"this global::TUnit.Mocks.Mock<{model.FullyQualifiedName}> mock"; + var fullParamList = string.IsNullOrEmpty(paramList) ? extensionParam : $"{extensionParam}, {paramList}"; + + using (writer.Block($"public static {returnType} {safeMemberName}{typeParams}({fullParamList}){constraints}")) + { + // Build matchers array + var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); + + if (nonOutParams.Count == 0) + { + writer.AppendLine("var matchers = global::System.Array.Empty();"); + } + else + { + var matcherArgs = string.Join(", ", nonOutParams.Select(p => $"{p.Name}.Matcher")); + writer.AppendLine($"var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] {{ {matcherArgs} }};"); + } + + if (useTypedWrapper) + { + var wrapperName = GetWrapperName(safeName, method); + writer.AppendLine($"return new {wrapperName}(mock.Engine, {method.MemberId}, \"{method.Name}\", matchers);"); + } + else if (method.IsVoid) + { + writer.AppendLine($"return new global::TUnit.Mocks.VoidMockMethodCall(mock.Engine, {method.MemberId}, \"{method.Name}\", matchers);"); + } + else + { + writer.AppendLine($"return new global::TUnit.Mocks.MockMethodCall<{setupReturnType}>(mock.Engine, {method.MemberId}, \"{method.Name}\", matchers);"); + } + } + } + + private static void GeneratePropertyExtensionBlock(CodeWriter writer, List props, MockTypeModel model, string safeName) + { + using (writer.Block($"extension(global::TUnit.Mocks.Mock<{model.FullyQualifiedName}> mock)")) + { + bool first = true; + foreach (var prop in props) + { + if (!first) writer.AppendLine(); + first = false; + + var getterMemberId = prop.HasGetter ? prop.MemberId.ToString() : "0"; + var setterMemberId = prop.HasSetter ? prop.SetterMemberId.ToString() : "0"; + var hasGetter = prop.HasGetter ? "true" : "false"; + var hasSetter = prop.HasSetter ? "true" : "false"; + + var safePropName = GetSafeMemberName(prop.Name); + + writer.AppendLine($"public global::TUnit.Mocks.PropertyMockCall<{prop.ReturnType}> {safePropName}"); + writer.AppendLine($" => new(mock.Engine, {getterMemberId}, {setterMemberId}, \"{prop.Name}\", {hasGetter}, {hasSetter});"); + } + } + } + + private static void GenerateRaiseExtensionMethods(CodeWriter writer, MockTypeModel model) + { + bool first = true; + foreach (var evt in model.Events) + { + if (!first) writer.AppendLine(); + first = false; + + var extensionParam = $"this global::TUnit.Mocks.Mock<{model.FullyQualifiedName}> mock"; + + var raiseParamStr = evt.RaiseParameterList.Length == 0 + ? "" + : string.Join(", ", evt.RaiseParameterList.Select(p => $"{p.FullyQualifiedType} {p.Name}")); + var raiseParams = string.IsNullOrEmpty(raiseParamStr) + ? extensionParam + : $"{extensionParam}, {raiseParamStr}"; + + string argsExpr; + if (evt.RaiseParameterList.Length == 0) + { + argsExpr = "null"; + } + else if (evt.RaiseParameterList.Length == 1) + { + argsExpr = $"(object?){evt.RaiseParameterList[0].Name}"; + } + else + { + var paramNames = string.Join(", ", evt.RaiseParameterList.Select(p => p.Name)); + argsExpr = $"(object?)new object?[] {{ {paramNames} }}"; + } + + using (writer.Block($"public static void Raise{evt.Name}({raiseParams})")) + { + writer.AppendLine($"((global::TUnit.Mocks.IRaisable)mock.Engine.Raisable!).RaiseEvent(\"{evt.Name}\", {argsExpr});"); + } + } + } + + private static string GetArgParameterList(MockMemberModel method) + { + // Only include non-out parameters as Arg in setup + return string.Join(", ", method.Parameters + .Where(p => p.Direction != ParameterDirection.Out) + .Select(p => $"global::TUnit.Mocks.Arguments.Arg<{p.FullyQualifiedType}> {p.Name}")); + } + + private static string GetTypeParameterList(MockMemberModel method) + { + if (method.TypeParameters.Length == 0) return ""; + return "<" + string.Join(", ", method.TypeParameters.Select(tp => tp.Name)) + ">"; + } + + private static string GetConstraintClauses(MockMemberModel method) + { + var clauses = new List(); + foreach (var tp in method.TypeParameters) + { + if (!string.IsNullOrEmpty(tp.Constraints)) + { + clauses.Add($"where {tp.Name} : {tp.Constraints}"); + } + } + return clauses.Count > 0 ? " " + string.Join(" ", clauses) : ""; + } +} diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockRaiseBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockRaiseBuilder.cs deleted file mode 100644 index 5c1b3578eb..0000000000 --- a/TUnit.Mocks.SourceGenerator/Builders/MockRaiseBuilder.cs +++ /dev/null @@ -1,67 +0,0 @@ -using TUnit.Mocks.SourceGenerator.Models; - -namespace TUnit.Mocks.SourceGenerator.Builders; - -internal static class MockRaiseBuilder -{ - public static string Build(MockTypeModel model) - { - var writer = new CodeWriter(); - var safeName = MockImplBuilder.GetSafeName(model.FullyQualifiedName); - - writer.AppendLine("// "); - writer.AppendLine("#nullable enable"); - writer.AppendLine(); - - using (writer.Block("namespace TUnit.Mocks.Generated")) - { - // Data holder class implementing marker interface - using (writer.Block($"public sealed class {safeName}_MockRaise : global::TUnit.Mocks.IMockRaise<{model.FullyQualifiedName}>")) - { - writer.AppendLine($"internal readonly {safeName}_MockImpl Impl;"); - writer.AppendLine(); - writer.AppendLine($"internal {safeName}_MockRaise({safeName}_MockImpl impl) => Impl = impl;"); - } - - writer.AppendLine(); - - // Extension methods class - using (writer.Block($"public static class {safeName}_MockRaiseExtensions")) - { - bool firstMember = true; - foreach (var evt in model.Events) - { - if (!firstMember) writer.AppendLine(); - firstMember = false; - GenerateRaiseMethod(writer, evt, model, safeName); - } - } - } - - return writer.ToString(); - } - - private static void GenerateRaiseMethod(CodeWriter writer, MockEventModel evt, MockTypeModel model, string safeName) - { - var extensionParam = $"this global::TUnit.Mocks.IMockRaise<{model.FullyQualifiedName}> raise"; - - // Build parameter list: extension param + raise parameters - var raiseParamStr = evt.RaiseParameterList.Length == 0 - ? "" - : string.Join(", ", evt.RaiseParameterList.Select(p => $"{p.FullyQualifiedType} {p.Name}")); - var raiseParams = string.IsNullOrEmpty(raiseParamStr) - ? extensionParam - : $"{extensionParam}, {raiseParamStr}"; - - // Build argument pass-through for the Raise_ call using structured parameter data - var raiseArgNames = evt.RaiseParameterList.Length == 0 - ? "" - : string.Join(", ", evt.RaiseParameterList.Select(p => p.Name)); - - using (writer.Block($"public static void {evt.Name}({raiseParams})")) - { - writer.AppendLine($"var r = ({safeName}_MockRaise)raise;"); - writer.AppendLine($"r.Impl.Raise_{evt.Name}({raiseArgNames});"); - } - } -} diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockSetupBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockSetupBuilder.cs deleted file mode 100644 index 632f42ef58..0000000000 --- a/TUnit.Mocks.SourceGenerator/Builders/MockSetupBuilder.cs +++ /dev/null @@ -1,480 +0,0 @@ -using TUnit.Mocks.SourceGenerator.Models; - -namespace TUnit.Mocks.SourceGenerator.Builders; - -internal static class MockSetupBuilder -{ - private const int MaxTypedParams = 8; - - public static string Build(MockTypeModel model) - { - var writer = new CodeWriter(); - var safeName = MockImplBuilder.GetSafeName(model.FullyQualifiedName); - var hasEvents = model.Events.Length > 0; - - writer.AppendLine("// "); - writer.AppendLine("#nullable enable"); - writer.AppendLine(); - - using (writer.Block("namespace TUnit.Mocks.Generated")) - { - // Data holder class implementing marker interface - using (writer.Block($"public sealed class {safeName}_MockSetup : global::TUnit.Mocks.IMockSetup<{model.FullyQualifiedName}>")) - { - writer.AppendLine($"internal readonly global::TUnit.Mocks.MockEngine<{model.FullyQualifiedName}> Engine;"); - writer.AppendLine(); - writer.AppendLine($"internal {safeName}_MockSetup(global::TUnit.Mocks.MockEngine<{model.FullyQualifiedName}> engine) => Engine = engine;"); - } - - writer.AppendLine(); - - // Extension methods class - using (writer.Block($"public static class {safeName}_MockSetupExtensions")) - { - bool firstMember = true; - - // Methods - foreach (var method in model.Methods) - { - if (!firstMember) writer.AppendLine(); - firstMember = false; - GenerateSetupMethod(writer, method, model, safeName); - } - - // Properties — extension properties via C# 14 extension blocks - var setupProps = model.Properties - .Where(p => !p.IsIndexer && (p.HasGetter || p.HasSetter)) - .ToList(); - if (setupProps.Count > 0) - { - if (!firstMember) writer.AppendLine(); - firstMember = false; - GenerateSetupPropertyExtensionBlock(writer, setupProps, model, safeName); - } - } - - // Generate typed wrapper structs for qualifying methods - foreach (var method in model.Methods) - { - if (!ShouldGenerateTypedWrapper(method, hasEvents)) continue; - writer.AppendLine(); - GenerateTypedWrapperStruct(writer, method, safeName, model.Events); - } - } - - return writer.ToString(); - } - - private static bool ShouldGenerateTypedWrapper(MockMemberModel method, bool hasEvents) - { - if (method.IsGenericMethod) return false; - - var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); - if (nonOutParams.Count == 0) return hasEvents; - return nonOutParams.Count <= MaxTypedParams; - } - - private static string GetWrapperName(string safeName, MockMemberModel method) - => $"{safeName}_{method.Name}_M{method.MemberId}_TypedSetup"; - - private static void GenerateTypedWrapperStruct(CodeWriter writer, MockMemberModel method, string safeName, - EquatableArray events) - { - var setupReturnType = method.IsAsync && !method.IsVoid - ? method.UnwrappedReturnType - : method.ReturnType; - - var wrapperName = GetWrapperName(safeName, method); - var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); - - if (method.IsVoid) - { - GenerateVoidTypedWrapper(writer, wrapperName, nonOutParams, events); - } - else - { - GenerateReturnTypedWrapper(writer, wrapperName, nonOutParams, setupReturnType, events); - } - } - - private static void GenerateReturnTypedWrapper(CodeWriter writer, string wrapperName, - List nonOutParams, string returnType, EquatableArray events) - { - var chainType = $"global::TUnit.Mocks.Setup.ISetupChain<{returnType}>"; - var setupInterface = $"global::TUnit.Mocks.Setup.IMethodSetup<{returnType}>"; - var builderType = $"global::TUnit.Mocks.Setup.MethodSetupBuilder<{returnType}>"; - - // Only implement both interfaces when there are events — the dual-interface pattern - // preserves the concrete wrapper type through the chain so RaisesX() stays accessible. - var interfaces = events.Length > 0 ? $" : {setupInterface}, {chainType}" : ""; - - writer.AppendLine("[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); - using (writer.Block($"public readonly struct {wrapperName}{interfaces}")) - { - writer.AppendLine($"private readonly {builderType} _inner;"); - writer.AppendLine(); - writer.AppendLine($"internal {wrapperName}({builderType} inner) => _inner = inner;"); - - if (events.Length > 0) - { - writer.AppendLine(); - - // Explicit IMethodSetup implementations - writer.AppendLine($"{chainType} {setupInterface}.Returns({returnType} value) => _inner.Returns(value);"); - writer.AppendLine($"{chainType} {setupInterface}.Returns(global::System.Func<{returnType}> factory) => _inner.Returns(factory);"); - writer.AppendLine($"{chainType} {setupInterface}.ReturnsSequentially(params {returnType}[] values) => _inner.ReturnsSequentially(values);"); - writer.AppendLine($"{chainType} {setupInterface}.Throws() => _inner.Throws();"); - writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Exception exception) => _inner.Throws(exception);"); - writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); - writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); - writer.AppendLine($"{chainType} {setupInterface}.Returns(global::System.Func factory) => _inner.Returns(factory);"); - writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory);"); - writer.AppendLine($"{chainType} {setupInterface}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); - writer.AppendLine($"{chainType} {setupInterface}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); - writer.AppendLine($"{chainType} {setupInterface}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); - writer.AppendLine(); - - // Explicit ISetupChain implementations - writer.AppendLine($"{setupInterface} {chainType}.Then() {{ _inner.Then(); return this; }}"); - writer.AppendLine($"{chainType} {chainType}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); - writer.AppendLine($"{chainType} {chainType}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); - writer.AppendLine($"{chainType} {chainType}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); - } - - writer.AppendLine(); - - // Public self-returning methods (preserve wrapper type through fluent chain) - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Returns({returnType} value) {{ _inner.Returns(value); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Returns(global::System.Func<{returnType}> factory) {{ _inner.Returns(factory); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} ReturnsSequentially(params {returnType}[] values) {{ _inner.ReturnsSequentially(values); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Throws() where TException : global::System.Exception, new() {{ _inner.Throws(); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Throws(global::System.Exception exception) {{ _inner.Throws(exception); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Returns(global::System.Func factory) {{ _inner.Returns(factory); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Throws(global::System.Func exceptionFactory) {{ _inner.Throws(exceptionFactory); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Raises(string eventName, object? args = null) {{ _inner.Raises(eventName, args); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} SetsOutParameter(int paramIndex, object? value) {{ _inner.SetsOutParameter(paramIndex, value); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} TransitionsTo(string stateName) {{ _inner.TransitionsTo(stateName); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Then() {{ _inner.Then(); return this; }}"); - - // Typed parameter overloads (only for methods with typed params) - if (nonOutParams.Count >= 1) - { - writer.AppendLine(); - GenerateTypedReturnsOverload(writer, nonOutParams, returnType, wrapperName); - writer.AppendLine(); - GenerateTypedCallbackOverload(writer, nonOutParams, wrapperName); - writer.AppendLine(); - GenerateTypedThrowsOverload(writer, nonOutParams, wrapperName); - } - - // Typed event raises - if (events.Length > 0) - { - writer.AppendLine(); - GenerateTypedEventRaises(writer, events, wrapperName); - } - } - } - - private static void GenerateVoidTypedWrapper(CodeWriter writer, string wrapperName, - List nonOutParams, EquatableArray events) - { - var chainType = "global::TUnit.Mocks.Setup.IVoidSetupChain"; - var setupInterface = "global::TUnit.Mocks.Setup.IVoidMethodSetup"; - var builderType = "global::TUnit.Mocks.Setup.VoidMethodSetupBuilder"; - - // Only implement both interfaces when there are events — the dual-interface pattern - // preserves the concrete wrapper type through the chain so RaisesX() stays accessible. - var interfaces = events.Length > 0 ? $" : {setupInterface}, {chainType}" : ""; - - writer.AppendLine($"[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]"); - using (writer.Block($"public readonly struct {wrapperName}{interfaces}")) - { - writer.AppendLine($"private readonly {builderType} _inner;"); - writer.AppendLine(); - writer.AppendLine($"internal {wrapperName}({builderType} inner) => _inner = inner;"); - - if (events.Length > 0) - { - writer.AppendLine(); - - // Explicit IVoidMethodSetup implementations - writer.AppendLine($"{chainType} {setupInterface}.Throws() => _inner.Throws();"); - writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Exception exception) => _inner.Throws(exception);"); - writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); - writer.AppendLine($"{chainType} {setupInterface}.Callback(global::System.Action callback) => _inner.Callback(callback);"); - writer.AppendLine($"{chainType} {setupInterface}.Throws(global::System.Func exceptionFactory) => _inner.Throws(exceptionFactory);"); - writer.AppendLine($"{chainType} {setupInterface}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); - writer.AppendLine($"{chainType} {setupInterface}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); - writer.AppendLine($"{chainType} {setupInterface}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); - writer.AppendLine(); - - // Explicit IVoidSetupChain implementations - writer.AppendLine($"{setupInterface} {chainType}.Then() {{ _inner.Then(); return this; }}"); - writer.AppendLine($"{chainType} {chainType}.Raises(string eventName, object? args) => _inner.Raises(eventName, args);"); - writer.AppendLine($"{chainType} {chainType}.SetsOutParameter(int paramIndex, object? value) => _inner.SetsOutParameter(paramIndex, value);"); - writer.AppendLine($"{chainType} {chainType}.TransitionsTo(string stateName) => _inner.TransitionsTo(stateName);"); - } - - writer.AppendLine(); - - // Public self-returning methods (preserve wrapper type through fluent chain) - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Throws() where TException : global::System.Exception, new() {{ _inner.Throws(); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Throws(global::System.Exception exception) {{ _inner.Throws(exception); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Callback(global::System.Action callback) {{ _inner.Callback(callback); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Throws(global::System.Func exceptionFactory) {{ _inner.Throws(exceptionFactory); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Raises(string eventName, object? args = null) {{ _inner.Raises(eventName, args); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} SetsOutParameter(int paramIndex, object? value) {{ _inner.SetsOutParameter(paramIndex, value); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} TransitionsTo(string stateName) {{ _inner.TransitionsTo(stateName); return this; }}"); - writer.AppendLine($"/// "); - writer.AppendLine($"public {wrapperName} Then() {{ _inner.Then(); return this; }}"); - - // Typed parameter overloads (only for methods with typed params) - if (nonOutParams.Count >= 1) - { - writer.AppendLine(); - GenerateTypedCallbackOverload(writer, nonOutParams, wrapperName); - writer.AppendLine(); - GenerateTypedThrowsOverload(writer, nonOutParams, wrapperName); - } - - // Typed event raises - if (events.Length > 0) - { - writer.AppendLine(); - GenerateTypedEventRaises(writer, events, wrapperName); - } - } - } - - private static void GenerateTypedReturnsOverload(CodeWriter writer, List nonOutParams, - string returnType, string wrapperName) - { - var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); - var funcType = $"global::System.Func<{typeList}, {returnType}>"; - var castArgs = BuildCastArgs(nonOutParams); - - writer.AppendLine("/// Configure a typed computed return value using the actual method parameters."); - using (writer.Block($"public {wrapperName} Returns({funcType} factory)")) - { - writer.AppendLine($"_inner.Returns(args => factory({castArgs}));"); - writer.AppendLine("return this;"); - } - } - - private static void GenerateTypedCallbackOverload(CodeWriter writer, List nonOutParams, - string wrapperName) - { - var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); - var actionType = $"global::System.Action<{typeList}>"; - var castArgs = BuildCastArgs(nonOutParams); - - writer.AppendLine("/// Execute a typed callback using the actual method parameters."); - using (writer.Block($"public {wrapperName} Callback({actionType} callback)")) - { - writer.AppendLine($"_inner.Callback(args => callback({castArgs}));"); - writer.AppendLine("return this;"); - } - } - - private static void GenerateTypedThrowsOverload(CodeWriter writer, List nonOutParams, - string wrapperName) - { - var typeList = string.Join(", ", nonOutParams.Select(p => p.FullyQualifiedType)); - var funcType = $"global::System.Func<{typeList}, global::System.Exception>"; - var castArgs = BuildCastArgs(nonOutParams); - - writer.AppendLine("/// Configure a typed computed exception using the actual method parameters."); - using (writer.Block($"public {wrapperName} Throws({funcType} exceptionFactory)")) - { - writer.AppendLine($"_inner.Throws(args => exceptionFactory({castArgs}));"); - writer.AppendLine("return this;"); - } - } - - private static void GenerateTypedEventRaises(CodeWriter writer, EquatableArray events, - string wrapperName) - { - bool first = true; - foreach (var evt in events) - { - if (!first) writer.AppendLine(); - first = false; - - var paramList = evt.RaiseParameterList.Length == 0 - ? "" - : string.Join(", ", evt.RaiseParameterList.Select(p => $"{p.FullyQualifiedType} {p.Name}")); - - string argsExpr; - if (evt.RaiseParameterList.Length == 0) - { - argsExpr = ""; - } - else if (evt.RaiseParameterList.Length == 1) - { - argsExpr = $", (object?){evt.RaiseParameterList[0].Name}"; - } - else - { - var argNames = string.Join(", ", evt.RaiseParameterList.Select(p => p.Name)); - argsExpr = $", (object?)new object?[] {{ {argNames} }}"; - } - - writer.AppendLine($"/// Auto-raise the {evt.Name} event when this method is called."); - writer.AppendLine($"public {wrapperName} Raises{evt.Name}({paramList}) {{ _inner.Raises(\"{evt.Name}\"{argsExpr}); return this; }}"); - } - } - - private static string BuildCastArgs(List nonOutParams) - { - return string.Join(", ", nonOutParams.Select((p, i) => - $"({p.FullyQualifiedType})args[{i}]!")); - } - - private static void GenerateSetupMethod(CodeWriter writer, MockMemberModel method, MockTypeModel model, string safeName) - { - // For async methods (Task/ValueTask), unwrap the return type so users write .Returns(5) not .Returns(Task.FromResult(5)) - // For void-async methods (Task/ValueTask), IsVoid is already true - var setupReturnType = method.IsAsync && !method.IsVoid - ? method.UnwrappedReturnType - : method.ReturnType; - - var hasEvents = model.Events.Length > 0; - var useTypedWrapper = ShouldGenerateTypedWrapper(method, hasEvents); - string returnType; - - if (useTypedWrapper) - { - returnType = GetWrapperName(safeName, method); - } - else if (method.IsVoid) - { - returnType = "global::TUnit.Mocks.Setup.IVoidMethodSetup"; - } - else - { - returnType = $"global::TUnit.Mocks.Setup.IMethodSetup<{setupReturnType}>"; - } - - var paramList = GetArgParameterList(method); - var typeParams = GetTypeParameterList(method); - var constraints = GetConstraintClauses(method); - - var extensionParam = $"this global::TUnit.Mocks.IMockSetup<{model.FullyQualifiedName}> setup"; - var fullParamList = string.IsNullOrEmpty(paramList) ? extensionParam : $"{extensionParam}, {paramList}"; - - using (writer.Block($"public static {returnType} {method.Name}{typeParams}({fullParamList}){constraints}")) - { - writer.AppendLine($"var s = ({safeName}_MockSetup)setup;"); - - // Build matchers array - var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); - - if (nonOutParams.Count == 0) - { - writer.AppendLine("var matchers = global::System.Array.Empty();"); - } - else - { - var matcherArgs = string.Join(", ", nonOutParams.Select(p => $"{p.Name}.Matcher")); - writer.AppendLine($"var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] {{ {matcherArgs} }};"); - } - - writer.AppendLine($"var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup({method.MemberId}, matchers, \"{method.Name}\");"); - writer.AppendLine("s.Engine.AddSetup(methodSetup);"); - - if (useTypedWrapper) - { - var wrapperName = GetWrapperName(safeName, method); - if (method.IsVoid) - { - writer.AppendLine($"return new {wrapperName}(new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup));"); - } - else - { - writer.AppendLine($"return new {wrapperName}(new global::TUnit.Mocks.Setup.MethodSetupBuilder<{setupReturnType}>(methodSetup));"); - } - } - else if (method.IsVoid) - { - writer.AppendLine("return new global::TUnit.Mocks.Setup.VoidMethodSetupBuilder(methodSetup);"); - } - else - { - writer.AppendLine($"return new global::TUnit.Mocks.Setup.MethodSetupBuilder<{setupReturnType}>(methodSetup);"); - } - } - } - - private static void GenerateSetupPropertyExtensionBlock(CodeWriter writer, List props, MockTypeModel model, string safeName) - { - using (writer.Block($"extension(global::TUnit.Mocks.IMockSetup<{model.FullyQualifiedName}> setup)")) - { - bool first = true; - foreach (var prop in props) - { - if (!first) writer.AppendLine(); - first = false; - - var getterMemberId = prop.HasGetter ? prop.MemberId.ToString() : "0"; - var setterMemberId = prop.HasSetter ? prop.SetterMemberId.ToString() : "0"; - var hasGetter = prop.HasGetter ? "true" : "false"; - var hasSetter = prop.HasSetter ? "true" : "false"; - - writer.AppendLine($"public global::TUnit.Mocks.Setup.PropertySetupAccessor<{prop.ReturnType}> {prop.Name}"); - writer.AppendLine($" => new((({safeName}_MockSetup)setup).Engine, {getterMemberId}, {setterMemberId}, \"{prop.Name}\", {hasGetter}, {hasSetter});"); - } - } - } - - private static string GetArgParameterList(MockMemberModel method) - { - // Only include non-out parameters as Arg in setup - return string.Join(", ", method.Parameters - .Where(p => p.Direction != ParameterDirection.Out) - .Select(p => $"global::TUnit.Mocks.Arguments.Arg<{p.FullyQualifiedType}> {p.Name}")); - } - - private static string GetTypeParameterList(MockMemberModel method) - { - if (method.TypeParameters.Length == 0) return ""; - return "<" + string.Join(", ", method.TypeParameters.Select(tp => tp.Name)) + ">"; - } - - private static string GetConstraintClauses(MockMemberModel method) - { - var clauses = new List(); - foreach (var tp in method.TypeParameters) - { - if (!string.IsNullOrEmpty(tp.Constraints)) - { - clauses.Add($"where {tp.Name} : {tp.Constraints}"); - } - } - return clauses.Count > 0 ? " " + string.Join(" ", clauses) : ""; - } -} diff --git a/TUnit.Mocks.SourceGenerator/Builders/MockVerifyBuilder.cs b/TUnit.Mocks.SourceGenerator/Builders/MockVerifyBuilder.cs deleted file mode 100644 index 0adb2674fb..0000000000 --- a/TUnit.Mocks.SourceGenerator/Builders/MockVerifyBuilder.cs +++ /dev/null @@ -1,133 +0,0 @@ -using TUnit.Mocks.SourceGenerator.Models; - -namespace TUnit.Mocks.SourceGenerator.Builders; - -internal static class MockVerifyBuilder -{ - public static string Build(MockTypeModel model) - { - var writer = new CodeWriter(); - var safeName = MockImplBuilder.GetSafeName(model.FullyQualifiedName); - - writer.AppendLine("// "); - writer.AppendLine("#nullable enable"); - writer.AppendLine(); - - using (writer.Block("namespace TUnit.Mocks.Generated")) - { - // Data holder class implementing marker interface - using (writer.Block($"public sealed class {safeName}_MockVerify : global::TUnit.Mocks.IMockVerify<{model.FullyQualifiedName}>")) - { - writer.AppendLine($"internal readonly global::TUnit.Mocks.MockEngine<{model.FullyQualifiedName}> Engine;"); - writer.AppendLine(); - writer.AppendLine($"internal {safeName}_MockVerify(global::TUnit.Mocks.MockEngine<{model.FullyQualifiedName}> engine) => Engine = engine;"); - } - - writer.AppendLine(); - - // Extension methods class - using (writer.Block($"public static class {safeName}_MockVerifyExtensions")) - { - bool firstMember = true; - - // Methods - foreach (var method in model.Methods) - { - if (!firstMember) writer.AppendLine(); - firstMember = false; - GenerateVerifyMethod(writer, method, model, safeName); - } - - // Properties — extension properties via C# 14 extension blocks - var verifyProps = model.Properties - .Where(p => !p.IsIndexer && (p.HasGetter || p.HasSetter)) - .ToList(); - if (verifyProps.Count > 0) - { - if (!firstMember) writer.AppendLine(); - firstMember = false; - GenerateVerifyPropertyExtensionBlock(writer, verifyProps, model, safeName); - } - } - } - - return writer.ToString(); - } - - private static void GenerateVerifyMethod(CodeWriter writer, MockMemberModel method, MockTypeModel model, string safeName) - { - var paramList = GetArgParameterList(method); - var typeParams = GetTypeParameterList(method); - var constraints = GetConstraintClauses(method); - - var extensionParam = $"this global::TUnit.Mocks.IMockVerify<{model.FullyQualifiedName}> verify"; - var fullParamList = string.IsNullOrEmpty(paramList) ? extensionParam : $"{extensionParam}, {paramList}"; - - using (writer.Block($"public static global::TUnit.Mocks.Verification.ICallVerification {method.Name}{typeParams}({fullParamList}){constraints}")) - { - writer.AppendLine($"var v = ({safeName}_MockVerify)verify;"); - - // Build matchers array - var nonOutParams = method.Parameters.Where(p => p.Direction != ParameterDirection.Out).ToList(); - - if (nonOutParams.Count == 0) - { - writer.AppendLine("var matchers = global::System.Array.Empty();"); - } - else - { - var matcherArgs = string.Join(", ", nonOutParams.Select(p => $"{p.Name}.Matcher")); - writer.AppendLine($"var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] {{ {matcherArgs} }};"); - } - - writer.AppendLine($"return new global::TUnit.Mocks.Verification.CallVerificationBuilder<{model.FullyQualifiedName}>(v.Engine, {method.MemberId}, \"{method.Name}\", matchers);"); - } - } - - private static void GenerateVerifyPropertyExtensionBlock(CodeWriter writer, List props, MockTypeModel model, string safeName) - { - using (writer.Block($"extension(global::TUnit.Mocks.IMockVerify<{model.FullyQualifiedName}> verify)")) - { - bool first = true; - foreach (var prop in props) - { - if (!first) writer.AppendLine(); - first = false; - - var getterMemberId = prop.HasGetter ? prop.MemberId.ToString() : "0"; - var setterMemberId = prop.HasSetter ? prop.SetterMemberId.ToString() : "0"; - var hasGetter = prop.HasGetter ? "true" : "false"; - var hasSetter = prop.HasSetter ? "true" : "false"; - - writer.AppendLine($"public global::TUnit.Mocks.Verification.PropertyVerifyAccessor<{prop.ReturnType}> {prop.Name}"); - writer.AppendLine($" => new((({safeName}_MockVerify)verify).Engine, {getterMemberId}, {setterMemberId}, \"{prop.Name}\", {hasGetter}, {hasSetter});"); - } - } - } - - private static string GetArgParameterList(MockMemberModel method) - { - return string.Join(", ", method.Parameters - .Where(p => p.Direction != ParameterDirection.Out) - .Select(p => $"global::TUnit.Mocks.Arguments.Arg<{p.FullyQualifiedType}> {p.Name}")); - } - - private static string GetTypeParameterList(MockMemberModel method) - { - if (method.TypeParameters.Length == 0) return ""; - return "<" + string.Join(", ", method.TypeParameters.Select(tp => tp.Name)) + ">"; - } - - private static string GetConstraintClauses(MockMemberModel method) - { - var clauses = new List(); - foreach (var tp in method.TypeParameters) - { - if (!string.IsNullOrEmpty(tp.Constraints)) - { - clauses.Add($"where {tp.Name} : {tp.Constraints}"); - } - } - return clauses.Count > 0 ? " " + string.Join(" ", clauses) : ""; - } -} diff --git a/TUnit.Mocks.SourceGenerator/MockGenerator.cs b/TUnit.Mocks.SourceGenerator/MockGenerator.cs index dbb54d9cf5..f133ffbee2 100644 --- a/TUnit.Mocks.SourceGenerator/MockGenerator.cs +++ b/TUnit.Mocks.SourceGenerator/MockGenerator.cs @@ -27,18 +27,18 @@ public void Initialize(IncrementalGeneratorInitializationContext context) { if (model.IsDelegateType) { - // Delegate mock: generate setup, verify, and delegate factory (no impl class) + // Delegate mock: generate members and delegate factory (no impl class) GenerateDelegateMock(spc, model); } else if (model.IsWrapMock) { - // Wrap mock: generate wrap impl, wrap factory, plus setup/verify + // Wrap mock: generate wrap impl, wrap factory, plus members GenerateWrapMock(spc, model); } else if (model.AdditionalInterfaceNames.Length > 0) { // Multi-interface mock: generate ONLY impl + factory - // Setup/verify/raise come from the single-type model (also emitted) + // Members/raise come from the single-type model (also emitted) GenerateMultiInterfaceMock(spc, model); } else @@ -57,20 +57,13 @@ private static void GenerateSingleTypeMock(SourceProductionContext spc, MockType var implSource = MockImplBuilder.Build(model); spc.AddSource($"{fileName}_MockImpl.g.cs", implSource); - // Generate setup surface - var setupSource = MockSetupBuilder.Build(model); - spc.AddSource($"{fileName}_MockSetup.g.cs", setupSource); + // Generate unified members surface (setup + verify) + var membersSource = MockMembersBuilder.Build(model); + spc.AddSource($"{fileName}_MockMembers.g.cs", membersSource); - // Generate verify surface - var verifySource = MockVerifyBuilder.Build(model); - spc.AddSource($"{fileName}_MockVerify.g.cs", verifySource); - - // Generate raise surface (if type has events) + // Generate events surface (if type has events) if (model.Events.Length > 0) { - var raiseSource = MockRaiseBuilder.Build(model); - spc.AddSource($"{fileName}_MockRaise.g.cs", raiseSource); - var eventsSource = MockEventsBuilder.Build(model); spc.AddSource($"{fileName}_MockEvents.g.cs", eventsSource); } @@ -84,13 +77,9 @@ private static void GenerateDelegateMock(SourceProductionContext spc, MockTypeMo { var fileName = GetSafeFileName(model); - // Generate setup surface (reuses standard builder — Invoke method is just a method) - var setupSource = MockSetupBuilder.Build(model); - spc.AddSource($"{fileName}_MockSetup.g.cs", setupSource); - - // Generate verify surface - var verifySource = MockVerifyBuilder.Build(model); - spc.AddSource($"{fileName}_MockVerify.g.cs", verifySource); + // Generate unified members surface (setup + verify) + var membersSource = MockMembersBuilder.Build(model); + spc.AddSource($"{fileName}_MockMembers.g.cs", membersSource); // Generate delegate factory (creates the delegate lambda + wraps in Mock) var factorySource = MockDelegateFactoryBuilder.Build(model); @@ -100,26 +89,18 @@ private static void GenerateDelegateMock(SourceProductionContext spc, MockTypeMo private static void GenerateWrapMock(SourceProductionContext spc, MockTypeModel model) { var fileName = GetSafeFileName(model); - var safeName = MockImplBuilder.GetCompositeSafeName(model); // Generate wrap mock implementation (delegates to wrapped instance for unconfigured calls) var implSource = MockImplBuilder.Build(model); spc.AddSource($"{fileName}_WrapMockImpl.g.cs", implSource); - // Generate setup surface (reuses standard builder — same setup class as OfPartial) - var setupSource = MockSetupBuilder.Build(model); - spc.AddSource($"{fileName}_MockSetup.g.cs", setupSource); + // Generate unified members surface (setup + verify) + var membersSource = MockMembersBuilder.Build(model); + spc.AddSource($"{fileName}_MockMembers.g.cs", membersSource); - // Generate verify surface - var verifySource = MockVerifyBuilder.Build(model); - spc.AddSource($"{fileName}_MockVerify.g.cs", verifySource); - - // Generate raise surface (if type has events) + // Generate events surface (if type has events) if (model.Events.Length > 0) { - var raiseSource = MockRaiseBuilder.Build(model); - spc.AddSource($"{fileName}_MockRaise.g.cs", raiseSource); - var eventsSource = MockEventsBuilder.Build(model); spc.AddSource($"{fileName}_MockEvents.g.cs", eventsSource); } diff --git a/TUnit.Mocks.Tests/AdditionalCoverageTests.cs b/TUnit.Mocks.Tests/AdditionalCoverageTests.cs index e9aa8bd2c5..c0c33427ac 100644 --- a/TUnit.Mocks.Tests/AdditionalCoverageTests.cs +++ b/TUnit.Mocks.Tests/AdditionalCoverageTests.cs @@ -24,7 +24,7 @@ public async Task Exception_Properties_Populated_On_Verification_Failure() // Act — verify wrong count var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(5)); + mock.Add(1, 2).WasCalled(Times.Exactly(5)); }); // Assert — all properties accessible @@ -43,7 +43,7 @@ public async Task Exception_Message_Contains_Custom_Message() // Act — verify with custom message var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Once, "Calculator Add was expected"); + mock.Add(1, 2).WasCalled(Times.Once, "Calculator Add was expected"); }); await Assert.That(ex.Message).Contains("Calculator Add was expected"); @@ -62,7 +62,7 @@ public async Task Exception_ActualCalls_Lists_All_Calls_To_Member() // Act — verify wrong specific args var ex = Assert.Throws(() => { - mock.Verify.Add(99, 99).WasCalled(Times.Once); + mock.Add(99, 99).WasCalled(Times.Once); }); // Assert — all 3 actual calls to Add are listed @@ -146,7 +146,7 @@ public class MockObjectAccessTests public async Task Object_Property_Returns_Mock_Implementation() { var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(3); + mock.Add(1, 2).Returns(3); var calc = mock.Object; var result = calc.Add(1, 2); @@ -207,7 +207,7 @@ public async Task VerifyAll_Message_Includes_Matcher_Descriptions() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Is(x => x > 0)).Returns(1); + mock.Add(Arg.Any(), Arg.Is(x => x > 0)).Returns(1); // Act — don't call the method @@ -222,9 +222,9 @@ public async Task VerifyAll_Message_Lists_Multiple_Uninvoked_Setups() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(3); - mock.Setup.GetName().Returns("name"); - mock.Setup.Log("msg"); + mock.Add(1, 2).Returns(3); + mock.GetName().Returns("name"); + mock.Log("msg"); // Act — don't call any methods @@ -240,8 +240,8 @@ public async Task VerifyAll_Passes_When_All_Setups_Invoked() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(1); - mock.Setup.GetName().Returns("name"); + mock.Add(Arg.Any(), Arg.Any()).Returns(1); + mock.GetName().Returns("name"); // Act — invoke all setups mock.Object.Add(1, 2); @@ -336,7 +336,7 @@ public async Task WasNeverCalled_With_Custom_Message() var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasNeverCalled("Add should not have been called"); + mock.Add(1, 2).WasNeverCalled("Add should not have been called"); }); await Assert.That(ex.Message).Contains("Add should not have been called"); @@ -350,7 +350,7 @@ public async Task WasCalled_No_Args_With_Custom_Message() var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled("Expected Add to be called"); + mock.Add(1, 2).WasCalled("Expected Add to be called"); }); await Assert.That(ex.Message).Contains("Expected Add to be called"); diff --git a/TUnit.Mocks.Tests/ArgumentMatcherTests.cs b/TUnit.Mocks.Tests/ArgumentMatcherTests.cs index 4db5095095..2926a712fc 100644 --- a/TUnit.Mocks.Tests/ArgumentMatcherTests.cs +++ b/TUnit.Mocks.Tests/ArgumentMatcherTests.cs @@ -13,7 +13,7 @@ public async Task Arg_Any_Matches_All_Values() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); // Act ICalculator calc = mock.Object; @@ -30,7 +30,7 @@ public async Task Arg_Is_With_Predicate_Matches_When_True() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Is(a => a > 0), Arg.Is(b => b > 0)).Returns(100); + mock.Add(Arg.Is(a => a > 0), Arg.Is(b => b > 0)).Returns(100); // Act ICalculator calc = mock.Object; @@ -50,7 +50,7 @@ public async Task Arg_Is_With_Exact_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Is(10), Arg.Is(20)).Returns(30); + mock.Add(Arg.Is(10), Arg.Is(20)).Returns(30); // Act ICalculator calc = mock.Object; @@ -69,7 +69,7 @@ public async Task Arg_Capture_Captures_Values() // Arrange var firstArg = Arg.Any(); var mock = Mock.Of(); - mock.Setup.Add(firstArg, Arg.Any()).Returns(1); + mock.Add(firstArg, Arg.Any()).Returns(1); // Act ICalculator calc = mock.Object; @@ -91,7 +91,7 @@ public async Task Mixed_Matchers_And_Exact_Values() // Arrange var mock = Mock.Of(); // First arg: any int. Second arg: exact 5. - mock.Setup.Add(Arg.Any(), 5).Returns(99); + mock.Add(Arg.Any(), 5).Returns(99); // Act ICalculator calc = mock.Object; @@ -111,7 +111,7 @@ public async Task Arg_IsNull_Matches_Null_Values() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.IsNull()).Returns("got null"); + mock.Greet(Arg.IsNull()).Returns("got null"); // Act IGreeter greeter = mock.Object; @@ -128,7 +128,7 @@ public async Task Arg_IsNotNull_Matches_NonNull_Values() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.IsNotNull()).Returns("got something"); + mock.Greet(Arg.IsNotNull()).Returns("got something"); // Act IGreeter greeter = mock.Object; @@ -148,7 +148,7 @@ public async Task Arg_Capture_With_String_Values() // Arrange var nameArg = Arg.Any(); var mock = Mock.Of(); - mock.Setup.Greet(nameArg).Returns("hi"); + mock.Greet(nameArg).Returns("hi"); // Act IGreeter greeter = mock.Object; @@ -167,8 +167,8 @@ public async Task Multiple_Setups_With_Different_Matchers() { // Arrange — more specific setup first, then broader var mock = Mock.Of(); - mock.Setup.Add(1, 1).Returns(100); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(1, 1).Returns(100); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); // Act ICalculator calc = mock.Object; @@ -183,8 +183,8 @@ public async Task Specific_Setup_After_Any_Takes_Precedence() { // Arrange — broad setup first, then specific var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); - mock.Setup.Add(1, 1).Returns(100); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(1, 1).Returns(100); // Act ICalculator calc = mock.Object; @@ -211,7 +211,7 @@ public async Task Arg_Capture_Does_Not_Capture_On_Partial_Match() // Arrange — setup requires first arg = any (captured), second arg starts with "prefix" var firstArg = Arg.Any(); var mock = Mock.Of(); - mock.Setup.Add(firstArg, Arg.Is(b => b > 100)).Returns(999); + mock.Add(firstArg, Arg.Is(b => b > 100)).Returns(999); ICalculator calc = mock.Object; @@ -235,7 +235,7 @@ public async Task Predicate_Matcher_With_String() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Is(s => s != null && s.StartsWith("A"))).Returns("starts with A"); + mock.Greet(Arg.Is(s => s != null && s.StartsWith("A"))).Returns("starts with A"); // Act IGreeter greeter = mock.Object; diff --git a/TUnit.Mocks.Tests/AsyncTests.cs b/TUnit.Mocks.Tests/AsyncTests.cs index 2681ee8944..a340b1e19c 100644 --- a/TUnit.Mocks.Tests/AsyncTests.cs +++ b/TUnit.Mocks.Tests/AsyncTests.cs @@ -26,7 +26,7 @@ public async Task Task_Int_Returns_Unwrapped_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.GetValueAsync().Returns(5); + mock.GetValueAsync().Returns(5); IAsyncService service = mock.Object; @@ -42,7 +42,7 @@ public async Task Task_String_Returns_Unwrapped_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.GetNameAsync(Arg.Any()).Returns("hello"); + mock.GetNameAsync(Arg.Any()).Returns("hello"); IAsyncService service = mock.Object; @@ -58,8 +58,8 @@ public async Task Task_String_With_Exact_Arg_Match() { // Arrange var mock = Mock.Of(); - mock.Setup.GetNameAsync("key1").Returns("value1"); - mock.Setup.GetNameAsync("key2").Returns("value2"); + mock.GetNameAsync("key1").Returns("value1"); + mock.GetNameAsync("key2").Returns("value2"); IAsyncService service = mock.Object; @@ -88,7 +88,7 @@ public async Task ValueTask_Int_Returns_Unwrapped_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.GetValueValueTaskAsync().Returns(42); + mock.GetValueValueTaskAsync().Returns(42); IAsyncService service = mock.Object; @@ -104,7 +104,7 @@ public async Task Async_Method_Throws_Returns_Faulted_Task() { // Arrange var mock = Mock.Of(); - mock.Setup.GetValueAsync().Throws(); + mock.GetValueAsync().Throws(); IAsyncService service = mock.Object; @@ -162,7 +162,7 @@ public async Task Async_Method_Sequential_Returns() { // Arrange var mock = Mock.Of(); - mock.Setup.GetValueAsync().ReturnsSequentially(10, 20, 30); + mock.GetValueAsync().ReturnsSequentially(10, 20, 30); IAsyncService service = mock.Object; @@ -179,7 +179,7 @@ public async Task Async_Method_Verify_Called() { // Arrange var mock = Mock.Of(); - mock.Setup.GetValueAsync().Returns(5); + mock.GetValueAsync().Returns(5); IAsyncService service = mock.Object; @@ -188,7 +188,7 @@ public async Task Async_Method_Verify_Called() await service.GetValueAsync(); // Assert — verify it was called twice - mock.Verify.GetValueAsync().WasCalled(Times.Exactly(2)); + mock.GetValueAsync().WasCalled(Times.Exactly(2)); await Assert.That(true).IsTrue(); } } diff --git a/TUnit.Mocks.Tests/AsyncVerificationTests.cs b/TUnit.Mocks.Tests/AsyncVerificationTests.cs index 2783cf42a5..03049533d2 100644 --- a/TUnit.Mocks.Tests/AsyncVerificationTests.cs +++ b/TUnit.Mocks.Tests/AsyncVerificationTests.cs @@ -9,12 +9,12 @@ public class AsyncVerificationTests public async Task WasCalled_Times_Once_Passes() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; _ = calc.Add(1, 2); - await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) + await Assert.That(mock.Add(Arg.Any(), Arg.Any())) .WasCalled(Times.Once); } @@ -22,14 +22,14 @@ await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) public async Task WasCalled_Times_Exactly_Passes() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; _ = calc.Add(1, 2); _ = calc.Add(3, 4); _ = calc.Add(5, 6); - await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) + await Assert.That(mock.Add(Arg.Any(), Arg.Any())) .WasCalled(Times.Exactly(3)); } @@ -37,13 +37,13 @@ await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) public async Task WasCalled_Wrong_Count_Fails() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; _ = calc.Add(1, 2); await Assert.ThrowsAsync(async () => - await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) + await Assert.That(mock.Add(Arg.Any(), Arg.Any())) .WasCalled(Times.Exactly(5))); } @@ -52,7 +52,7 @@ public async Task WasNeverCalled_Passes_When_Not_Called() { var mock = Mock.Of(); - await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) + await Assert.That(mock.Add(Arg.Any(), Arg.Any())) .WasNeverCalled(); } @@ -60,13 +60,13 @@ await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) public async Task WasNeverCalled_Fails_When_Called() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; _ = calc.Add(1, 2); await Assert.ThrowsAsync(async () => - await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) + await Assert.That(mock.Add(Arg.Any(), Arg.Any())) .WasNeverCalled()); } @@ -74,13 +74,13 @@ await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) public async Task WasCalled_AtLeastOnce_Passes() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; _ = calc.Add(1, 2); _ = calc.Add(3, 4); - await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) + await Assert.That(mock.Add(Arg.Any(), Arg.Any())) .WasCalled(Times.AtLeastOnce); } @@ -88,13 +88,13 @@ await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) public async Task Property_Getter_WasCalled_Via_Assert() { var mock = Mock.Of(); - mock.Setup.Name.Returns("Calculator"); + mock.Name.Returns("Calculator"); IPropertyService svc = mock.Object; _ = svc.Name; _ = svc.Name; - await Assert.That(mock.Verify.Name) + await Assert.That(mock.Name) .WasCalled(Times.Exactly(2)); } @@ -106,7 +106,7 @@ public async Task Property_Setter_WasCalled_Via_Assert() IPropertyService svc = mock.Object; svc.Count = 10; - await Assert.That(mock.Verify.Count.Setter) + await Assert.That(mock.Count.Setter) .WasCalled(Times.Once); } @@ -115,7 +115,7 @@ public async Task Property_Getter_WasNeverCalled_Via_Assert() { var mock = Mock.Of(); - await Assert.That(mock.Verify.Name) + await Assert.That(mock.Name) .WasNeverCalled(); } @@ -123,18 +123,18 @@ await Assert.That(mock.Verify.Name) public async Task Multiple_Verifications_In_Sequence() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); - mock.Setup.GetName().Returns("test"); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.GetName().Returns("test"); ICalculator calc = mock.Object; _ = calc.Add(1, 2); _ = calc.GetName(); _ = calc.GetName(); - await Assert.That(mock.Verify.Add(Arg.Any(), Arg.Any())) + await Assert.That(mock.Add(Arg.Any(), Arg.Any())) .WasCalled(Times.Once); - await Assert.That(mock.Verify.GetName()) + await Assert.That(mock.GetName()) .WasCalled(Times.Exactly(2)); } } diff --git a/TUnit.Mocks.Tests/AutoMockTests.cs b/TUnit.Mocks.Tests/AutoMockTests.cs index db040cf275..2908f18212 100644 --- a/TUnit.Mocks.Tests/AutoMockTests.cs +++ b/TUnit.Mocks.Tests/AutoMockTests.cs @@ -132,7 +132,7 @@ public async Task Auto_Mock_Configurable_Via_GetAutoMock() // Retrieve and configure the auto-mock var autoMock = mock.GetAutoMock("GetServiceB"); - autoMock.Setup.GetValue().Returns(42); + autoMock.GetValue().Returns(42); // Act var value = serviceB.GetValue(); @@ -146,7 +146,7 @@ public void Strict_Mode_Does_Not_Auto_Mock() { // Arrange var mock = Mock.Of(MockBehavior.Strict); - mock.Setup.GetName().Returns("test"); + mock.GetName().Returns("test"); // Act & Assert — strict mode throws for unconfigured method Assert.Throws(() => @@ -161,8 +161,8 @@ public async Task Explicit_Setup_Overrides_Auto_Mock() // Arrange var mock = Mock.Of(); var customServiceB = Mock.Of(); - customServiceB.Setup.GetValue().Returns(99); - mock.Setup.GetServiceB().Returns(customServiceB.Object); + customServiceB.GetValue().Returns(99); + mock.GetServiceB().Returns(customServiceB.Object); // Act var serviceB = mock.Object.GetServiceB(); diff --git a/TUnit.Mocks.Tests/AutoRaiseEventTests.cs b/TUnit.Mocks.Tests/AutoRaiseEventTests.cs index f0049421b6..6c02ebfbe4 100644 --- a/TUnit.Mocks.Tests/AutoRaiseEventTests.cs +++ b/TUnit.Mocks.Tests/AutoRaiseEventTests.cs @@ -25,7 +25,7 @@ public async Task Raises_Event_When_Method_Returns_Value() mock.Object.StatusChanged += (sender, status) => receivedStatus = status; - mock.Setup.Process(Arg.Any()) + mock.Process(Arg.Any()) .Returns(true) .RaisesStatusChanged("completed"); @@ -42,7 +42,7 @@ public async Task Raises_Event_When_Void_Method_Called() mock.Object.StatusChanged += (sender, status) => receivedStatus = status; - mock.Setup.Execute(Arg.Any()) + mock.Execute(Arg.Any()) .RaisesStatusChanged("executed"); mock.Object.Execute("run"); @@ -58,7 +58,7 @@ public async Task Multiple_Raises_Fire_In_Order() mock.Object.StatusChanged += (sender, status) => receivedStatuses.Add(status); - mock.Setup.Process(Arg.Any()) + mock.Process(Arg.Any()) .Returns(true) .RaisesStatusChanged("first") .RaisesStatusChanged("second"); @@ -75,7 +75,7 @@ public async Task Raises_With_No_Subscribers_Does_Not_Throw() { var mock = Mock.Of(); - mock.Setup.Process(Arg.Any()) + mock.Process(Arg.Any()) .Returns(true) .RaisesStatusChanged("ignored"); @@ -93,7 +93,7 @@ public async Task Raises_On_Each_Call() mock.Object.StatusChanged += (sender, status) => callCount++; - mock.Setup.Process(Arg.Any()) + mock.Process(Arg.Any()) .Returns(true) .RaisesStatusChanged("ping"); @@ -112,7 +112,7 @@ public async Task Raises_Event_From_Zero_Param_Void_Method() mock.Object.OnSimple += () => wasCalled = true; - mock.Setup.Trigger() + mock.Trigger() .RaisesOnSimple(); mock.Object.Trigger(); @@ -128,7 +128,7 @@ public async Task Raises_Event_From_Zero_Param_Return_Method() mock.Object.OnSimple += () => wasCalled = true; - mock.Setup.Query() + mock.Query() .Returns("result") .RaisesOnSimple(); @@ -151,7 +151,7 @@ public async Task Raises_Multi_Param_Event_Unpacks_Arguments() receivedCount = count; }; - mock.Setup.Trigger() + mock.Trigger() .RaisesOnMultiParam("hello", 42); mock.Object.Trigger(); diff --git a/TUnit.Mocks.Tests/AutoTrackPropertyTests.cs b/TUnit.Mocks.Tests/AutoTrackPropertyTests.cs index 3de25eb9d1..543f1d203a 100644 --- a/TUnit.Mocks.Tests/AutoTrackPropertyTests.cs +++ b/TUnit.Mocks.Tests/AutoTrackPropertyTests.cs @@ -69,7 +69,7 @@ public async Task Explicit_Setup_Overrides_AutoTrack() // Arrange var mock = Mock.Of(); mock.SetupAllProperties(); - mock.Setup.Name.Returns("Configured"); + mock.Name.Returns("Configured"); // Act — set a tracked value, but explicit setup should win mock.Object.Name = "Tracked"; @@ -125,8 +125,8 @@ public async Task Strict_Mode_Does_Not_AutoTrack_By_Default() { // Arrange — strict mode requires explicit SetupAllProperties var mock = Mock.Of(MockBehavior.Strict); - mock.Setup.Name.Set(Arg.Any()); - mock.Setup.Name.Returns(""); + mock.Name.Set(Arg.Any()); + mock.Name.Returns(""); // Act mock.Object.Name = "Alice"; @@ -141,8 +141,8 @@ public async Task Strict_Mode_With_SetupAllProperties_Tracks() // Arrange — strict mode with explicit opt-in var mock = Mock.Of(MockBehavior.Strict); mock.SetupAllProperties(); - mock.Setup.Name.Set(Arg.Any()); - mock.Setup.Name.Returns(""); + mock.Name.Set(Arg.Any()); + mock.Name.Returns(""); // Act mock.Object.Name = "Alice"; diff --git a/TUnit.Mocks.Tests/BasicMockTests.cs b/TUnit.Mocks.Tests/BasicMockTests.cs index f6c98e236a..e28facf8d0 100644 --- a/TUnit.Mocks.Tests/BasicMockTests.cs +++ b/TUnit.Mocks.Tests/BasicMockTests.cs @@ -39,7 +39,7 @@ public async Task Setup_Returns_Configures_Return_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(2, 3).Returns(5); + mock.Add(2, 3).Returns(5); // Act ICalculator calc = mock.Object; @@ -54,7 +54,7 @@ public async Task Setup_Returns_With_String() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet("Alice").Returns("Hello, Alice!"); + mock.Greet("Alice").Returns("Hello, Alice!"); // Act IGreeter greeter = mock.Object; @@ -96,8 +96,8 @@ public async Task Multiple_Setups_Last_Wins() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 1).Returns(10); - mock.Setup.Add(1, 1).Returns(20); // Last setup wins + mock.Add(1, 1).Returns(10); + mock.Add(1, 1).Returns(20); // Last setup wins // Act ICalculator calc = mock.Object; @@ -112,8 +112,8 @@ public async Task Different_Args_Different_Returns() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(3); - mock.Setup.Add(10, 20).Returns(30); + mock.Add(1, 2).Returns(3); + mock.Add(10, 20).Returns(30); // Act ICalculator calc = mock.Object; @@ -154,7 +154,7 @@ public async Task Reset_Clears_Setups() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 1).Returns(42); + mock.Add(1, 1).Returns(42); ICalculator calc = mock.Object; await Assert.That(calc.Add(1, 1)).IsEqualTo(42); diff --git a/TUnit.Mocks.Tests/CallbackTests.cs b/TUnit.Mocks.Tests/CallbackTests.cs index 33d0a8c7ad..8b109ebf69 100644 --- a/TUnit.Mocks.Tests/CallbackTests.cs +++ b/TUnit.Mocks.Tests/CallbackTests.cs @@ -14,7 +14,7 @@ public async Task Callback_Is_Invoked_When_Method_Is_Called() // Arrange var callbackInvoked = false; var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Callback(() => callbackInvoked = true); ICalculator calc = mock.Object; @@ -32,7 +32,7 @@ public async Task Callback_With_Returns_Both_Execute() // Arrange var callbackInvoked = false; var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Callback(() => callbackInvoked = true) .Then() .Returns(42); @@ -55,7 +55,7 @@ public async Task Multiple_Callbacks_Via_Chaining() // Arrange var callCount = 0; var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Callback(() => callCount++) .Then() .Callback(() => callCount += 10); @@ -76,7 +76,7 @@ public async Task Callback_Invoked_For_Each_Call() // Arrange var callCount = 0; var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Callback(() => callCount++); ICalculator calc = mock.Object; @@ -96,7 +96,7 @@ public async Task Callback_On_Method_With_Return_Value() // Arrange var lastArgs = ""; var mock = Mock.Of(); - mock.Setup.Greet(Arg.Any()) + mock.Greet(Arg.Any()) .Callback(() => lastArgs = "called") .Then() .Returns("hello"); @@ -120,7 +120,7 @@ public async Task Computed_Return_Via_Factory() // Arrange var counter = 0; var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Returns(() => ++counter); ICalculator calc = mock.Object; diff --git a/TUnit.Mocks.Tests/CollectionMatcherTests.cs b/TUnit.Mocks.Tests/CollectionMatcherTests.cs index 5fda258b29..0760d8fb74 100644 --- a/TUnit.Mocks.Tests/CollectionMatcherTests.cs +++ b/TUnit.Mocks.Tests/CollectionMatcherTests.cs @@ -21,7 +21,7 @@ public async Task Arg_Contains_Matches_List_With_Item() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.Contains, int>(42)).Returns(1); + mock.ProcessItems(Arg.Contains, int>(42)).Returns(1); // Act var svc = mock.Object; @@ -36,7 +36,7 @@ public async Task Arg_Contains_Does_Not_Match_Without_Item() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.Contains, int>(42)).Returns(1); + mock.ProcessItems(Arg.Contains, int>(42)).Returns(1); // Act var svc = mock.Object; @@ -51,7 +51,7 @@ public async Task Arg_HasCount_Matches_List_With_Exact_Count() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.HasCount>(3)).Returns(99); + mock.ProcessItems(Arg.HasCount>(3)).Returns(99); // Act var svc = mock.Object; @@ -66,7 +66,7 @@ public async Task Arg_HasCount_Does_Not_Match_Wrong_Count() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.HasCount>(3)).Returns(99); + mock.ProcessItems(Arg.HasCount>(3)).Returns(99); // Act var svc = mock.Object; @@ -81,7 +81,7 @@ public async Task Arg_IsEmpty_Matches_Empty_List() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.IsEmpty>()).Returns(77); + mock.ProcessItems(Arg.IsEmpty>()).Returns(77); // Act var svc = mock.Object; @@ -95,7 +95,7 @@ public async Task Arg_IsEmpty_Does_Not_Match_NonEmpty() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.IsEmpty>()).Returns(77); + mock.ProcessItems(Arg.IsEmpty>()).Returns(77); // Act var svc = mock.Object; @@ -109,7 +109,7 @@ public async Task Arg_SequenceEquals_Matches_Exact_Sequence() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.SequenceEquals, int>(new[] { 1, 2, 3 })).Returns(55); + mock.ProcessItems(Arg.SequenceEquals, int>(new[] { 1, 2, 3 })).Returns(55); // Act var svc = mock.Object; @@ -123,7 +123,7 @@ public async Task Arg_SequenceEquals_Does_Not_Match_Different_Sequence() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessItems(Arg.SequenceEquals, int>(new[] { 1, 2, 3 })).Returns(55); + mock.ProcessItems(Arg.SequenceEquals, int>(new[] { 1, 2, 3 })).Returns(55); // Act var svc = mock.Object; @@ -139,7 +139,7 @@ public async Task Arg_SequenceEquals_With_Strings() { // Arrange var mock = Mock.Of(); - mock.Setup.JoinNames(Arg.SequenceEquals, string>(new[] { "a", "b" })).Returns("matched"); + mock.JoinNames(Arg.SequenceEquals, string>(new[] { "a", "b" })).Returns("matched"); // Act var svc = mock.Object; @@ -155,7 +155,7 @@ public async Task Arg_Contains_With_Strings() { // Arrange var mock = Mock.Of(); - mock.Setup.JoinNames(Arg.Contains, string>("hello")).Returns("found"); + mock.JoinNames(Arg.Contains, string>("hello")).Returns("found"); // Act var svc = mock.Object; diff --git a/TUnit.Mocks.Tests/CustomDelegateEventTests.cs b/TUnit.Mocks.Tests/CustomDelegateEventTests.cs index f82d396441..e2d9377d05 100644 --- a/TUnit.Mocks.Tests/CustomDelegateEventTests.cs +++ b/TUnit.Mocks.Tests/CustomDelegateEventTests.cs @@ -26,7 +26,7 @@ public async Task Raise_Action_Event() mock.Object.OnSimpleAction += () => wasCalled = true; // Act - mock.Raise!.OnSimpleAction(); + mock.RaiseOnSimpleAction(); // Assert await Assert.That(wasCalled).IsTrue(); @@ -42,7 +42,7 @@ public async Task Raise_Action_String_Event() mock.Object.OnStringAction += value => receivedValue = value; // Act - mock.Raise!.OnStringAction("hello"); + mock.RaiseOnStringAction("hello"); // Assert await Assert.That(receivedValue).IsEqualTo("hello"); @@ -63,7 +63,7 @@ public async Task Raise_MultiParam_Action_Event() }; // Act - mock.Raise!.OnMultiParamAction("Alice", 30); + mock.RaiseOnMultiParamAction("Alice", 30); // Assert await Assert.That(receivedName).IsEqualTo("Alice"); @@ -80,7 +80,7 @@ public async Task Raise_Standard_EventHandler_Still_Works() mock.Object.OnStandardEvent += (sender, e) => receivedValue = e; // Act - mock.Raise!.OnStandardEvent("world"); + mock.RaiseOnStandardEvent("world"); // Assert await Assert.That(receivedValue).IsEqualTo("world"); @@ -97,7 +97,7 @@ public async Task Multiple_Subscribers_All_Notified() mock.Object.OnStringAction += val => results.Add("sub2:" + val); // Act - mock.Raise!.OnStringAction("test"); + mock.RaiseOnStringAction("test"); // Assert await Assert.That(results).Count().IsEqualTo(2); @@ -116,9 +116,9 @@ public async Task Unsubscribe_Stops_Notifications() mock.Object.OnStringAction += handler; // Act — raise, unsubscribe, raise again - mock.Raise!.OnStringAction("first"); + mock.RaiseOnStringAction("first"); mock.Object.OnStringAction -= handler; - mock.Raise!.OnStringAction("second"); + mock.RaiseOnStringAction("second"); // Assert await Assert.That(callCount).IsEqualTo(1); @@ -131,8 +131,8 @@ public async Task No_Subscribers_Does_Not_Throw() var mock = Mock.Of(); // Act & Assert — should not throw - mock.Raise!.OnSimpleAction(); - mock.Raise!.OnStringAction("nobody"); - mock.Raise!.OnMultiParamAction("nobody", 0); + mock.RaiseOnSimpleAction(); + mock.RaiseOnStringAction("nobody"); + mock.RaiseOnMultiParamAction("nobody", 0); } } diff --git a/TUnit.Mocks.Tests/CustomMatcherTests.cs b/TUnit.Mocks.Tests/CustomMatcherTests.cs index 182ede997f..ce32217ce7 100644 --- a/TUnit.Mocks.Tests/CustomMatcherTests.cs +++ b/TUnit.Mocks.Tests/CustomMatcherTests.cs @@ -55,7 +55,7 @@ public async Task Custom_String_Length_Matcher() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Matches(new StringLengthMatcher(3, 10))).Returns("valid"); + mock.Greet(Arg.Matches(new StringLengthMatcher(3, 10))).Returns("valid"); // Act var greeter = mock.Object; @@ -72,7 +72,7 @@ public async Task Custom_Range_Matcher_With_Calculator() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Matches(new RangeMatcher(1, 10)), Arg.Any()).Returns(100); + mock.Add(Arg.Matches(new RangeMatcher(1, 10)), Arg.Any()).Returns(100); // Act var calc = mock.Object; @@ -90,7 +90,7 @@ public async Task Custom_Matcher_With_Predicate_Combined() { // Arrange — custom matcher for first arg, predicate for second var mock = Mock.Of(); - mock.Setup.Add(Arg.Matches(new RangeMatcher(0, 100)), Arg.Is(b => b > 0)).Returns(42); + mock.Add(Arg.Matches(new RangeMatcher(0, 100)), Arg.Is(b => b > 0)).Returns(42); // Act var calc = mock.Object; @@ -117,7 +117,7 @@ public async Task Custom_Matcher_With_Verification() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(0); + mock.Add(Arg.Any(), Arg.Any()).Returns(0); // Act var calc = mock.Object; @@ -125,7 +125,7 @@ public async Task Custom_Matcher_With_Verification() calc.Add(50, 100); // Verify — using custom matcher in verification - mock.Verify.Add(Arg.Matches(new RangeMatcher(1, 10)), Arg.Any()).WasCalled(Times.Once); - mock.Verify.Add(Arg.Matches(new RangeMatcher(40, 60)), Arg.Any()).WasCalled(Times.Once); + mock.Add(Arg.Matches(new RangeMatcher(1, 10)), Arg.Any()).WasCalled(Times.Once); + mock.Add(Arg.Matches(new RangeMatcher(40, 60)), Arg.Any()).WasCalled(Times.Once); } } diff --git a/TUnit.Mocks.Tests/DefaultValueProviderTests.cs b/TUnit.Mocks.Tests/DefaultValueProviderTests.cs index 56b68e5ade..fe16f34702 100644 --- a/TUnit.Mocks.Tests/DefaultValueProviderTests.cs +++ b/TUnit.Mocks.Tests/DefaultValueProviderTests.cs @@ -61,7 +61,7 @@ public async Task Setup_Takes_Precedence_Over_Provider() // Arrange var mock = Mock.Of(); mock.DefaultValueProvider = new CustomProvider(); - mock.Setup.Add(1, 2).Returns(100); + mock.Add(1, 2).Returns(100); ICalculator calc = mock.Object; diff --git a/TUnit.Mocks.Tests/DelegateMockTests.cs b/TUnit.Mocks.Tests/DelegateMockTests.cs index f5b20feb65..bbc9b977c0 100644 --- a/TUnit.Mocks.Tests/DelegateMockTests.cs +++ b/TUnit.Mocks.Tests/DelegateMockTests.cs @@ -8,7 +8,7 @@ public class DelegateMockTests public async Task Func_Returns_Configured_Value() { var mock = Mock.OfDelegate>(); - mock.Setup.Invoke(Arg.Any()).Returns(42); + mock.Invoke(Arg.Any()).Returns(42); var result = mock.Object("hello"); @@ -32,14 +32,14 @@ public async Task Action_Can_Be_Invoked_And_Verified() mock.Object("hello"); - mock.Verify!.Invoke("hello").WasCalled(Times.Once); + mock.Invoke("hello").WasCalled(Times.Once); } [Test] public async Task Custom_Delegate_Returns_Configured_Value() { var mock = Mock.OfDelegate(); - mock.Setup.Invoke(Arg.Any(), Arg.Any()).Returns(100); + mock.Invoke(Arg.Any(), Arg.Any()).Returns(100); var result = mock.Object(3, 5); @@ -50,7 +50,7 @@ public async Task Custom_Delegate_Returns_Configured_Value() public async Task Func_Throws_When_Configured() { var mock = Mock.OfDelegate>(); - mock.Setup.Invoke(Arg.Any()).Throws(); + mock.Invoke(Arg.Any()).Throws(); var act = () => mock.Object("test"); @@ -63,7 +63,7 @@ public async Task Func_Callback_Fires() var mock = Mock.OfDelegate>(); var callbackFired = false; - mock.Setup.Invoke(Arg.Any()) + mock.Invoke(Arg.Any()) .Callback(() => callbackFired = true) .Then() .Returns(1); @@ -78,7 +78,7 @@ public async Task Func_Arg_Capture_Works() { var mock = Mock.OfDelegate>(); var nameArg = Arg.Any(); - mock.Setup.Invoke(nameArg).Returns(1); + mock.Invoke(nameArg).Returns(1); mock.Object("first"); mock.Object("second"); @@ -92,12 +92,12 @@ public async Task Func_Arg_Capture_Works() public async Task Func_Verify_WasCalled() { var mock = Mock.OfDelegate>(); - mock.Setup.Invoke(Arg.Any()).Returns(1); + mock.Invoke(Arg.Any()).Returns(1); mock.Object("a"); mock.Object("b"); - mock.Verify!.Invoke(Arg.Any()).WasCalled(Times.Exactly(2)); + mock.Invoke(Arg.Any()).WasCalled(Times.Exactly(2)); } [Test] @@ -114,7 +114,7 @@ public async Task Action_Strict_Mode_Throws_On_Unconfigured_Call() public async Task Func_Implicit_Conversion_Works() { var mock = Mock.OfDelegate>(); - mock.Setup.Invoke(Arg.Any()).Returns(99); + mock.Invoke(Arg.Any()).Returns(99); Func func = mock; var result = func(5); diff --git a/TUnit.Mocks.Tests/DiagnosticsTests.cs b/TUnit.Mocks.Tests/DiagnosticsTests.cs index 61f2a3826e..aaec7c574b 100644 --- a/TUnit.Mocks.Tests/DiagnosticsTests.cs +++ b/TUnit.Mocks.Tests/DiagnosticsTests.cs @@ -10,8 +10,8 @@ public async Task Unused_Setups_Detected() var mock = Mock.Of(); // Configure two setups but only exercise one - mock.Setup.Add(1, 2).Returns(3); - mock.Setup.Add(10, 20).Returns(30); + mock.Add(1, 2).Returns(3); + mock.Add(10, 20).Returns(30); ICalculator calc = mock.Object; _ = calc.Add(1, 2); // only exercise the first setup @@ -30,7 +30,7 @@ public async Task Unmatched_Calls_Detected() var mock = Mock.Of(); // Configure setup only for specific args - mock.Setup.Add(1, 2).Returns(3); + mock.Add(1, 2).Returns(3); ICalculator calc = mock.Object; _ = calc.Add(1, 2); // matches setup @@ -47,7 +47,7 @@ public async Task All_Setups_Exercised() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; _ = calc.Add(1, 2); @@ -64,8 +64,8 @@ public async Task No_Calls_Means_All_Setups_Unused() { var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(3); - mock.Setup.Add(3, 4).Returns(7); + mock.Add(1, 2).Returns(3); + mock.Add(3, 4).Returns(7); var diag = mock.GetDiagnostics(); @@ -78,7 +78,7 @@ public async Task No_Calls_Means_All_Setups_Unused() public async Task Matcher_Descriptions_Populated() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Is(x => x > 0)).Returns(1); + mock.Add(Arg.Any(), Arg.Is(x => x > 0)).Returns(1); var diag = mock.GetDiagnostics(); @@ -93,7 +93,7 @@ public async Task Matcher_Descriptions_Populated() public async Task Reset_Clears_Diagnostics() { var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(3); + mock.Add(1, 2).Returns(3); ICalculator calc = mock.Object; _ = calc.Add(5, 5); // unmatched diff --git a/TUnit.Mocks.Tests/EdgeCaseTests.cs b/TUnit.Mocks.Tests/EdgeCaseTests.cs index c2a5feed84..bf1eca5076 100644 --- a/TUnit.Mocks.Tests/EdgeCaseTests.cs +++ b/TUnit.Mocks.Tests/EdgeCaseTests.cs @@ -131,8 +131,8 @@ public async Task Overload_Int_Vs_String_Different_Setups() { // Arrange var mock = Mock.Of(); - mock.Setup.Format(42).Returns("int:42"); - mock.Setup.Format("hello").Returns("str:hello"); + mock.Format(42).Returns("int:42"); + mock.Format("hello").Returns("str:hello"); // Act IOverloadedService svc = mock.Object; @@ -149,8 +149,8 @@ public async Task Overload_Two_Params_Different_Signatures() { // Arrange var mock = Mock.Of(); - mock.Setup.Format(10, "PREFIX").Returns("int-string:PREFIX10"); - mock.Setup.Format(3.14, 2).Returns("double-int:3.14:2"); + mock.Format(10, "PREFIX").Returns("int-string:PREFIX10"); + mock.Format(3.14, 2).Returns("double-int:3.14:2"); // Act IOverloadedService svc = mock.Object; @@ -169,9 +169,9 @@ public async Task Overload_Void_With_Optional_Bool() var singleArgCalled = false; var twoArgCalled = false; var mock = Mock.Of(); - mock.Setup.Process(Arg.Any()) + mock.Process(Arg.Any()) .Callback(() => singleArgCalled = true); - mock.Setup.Process(Arg.Any(), Arg.Any()) + mock.Process(Arg.Any(), Arg.Any()) .Callback(() => twoArgCalled = true); // Act @@ -189,8 +189,8 @@ public async Task Overload_Verify_Specific_Overload() { // Arrange var mock = Mock.Of(); - mock.Setup.Format(Arg.Any()).Returns("int"); - mock.Setup.Format(Arg.Any()).Returns("string"); + mock.Format(Arg.Any()).Returns("int"); + mock.Format(Arg.Any()).Returns("string"); // Act IOverloadedService svc = mock.Object; @@ -199,8 +199,8 @@ public async Task Overload_Verify_Specific_Overload() svc.Format("abc"); // Assert — verify only the int overload was called twice - mock.Verify.Format(Arg.Any()).WasCalled(Times.Exactly(2)); - mock.Verify.Format(Arg.Any()).WasCalled(Times.Once); + mock.Format(Arg.Any()).WasCalled(Times.Exactly(2)); + mock.Format(Arg.Any()).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } } @@ -215,7 +215,7 @@ public async Task Seven_Parameter_Method_With_Mixed_Matchers() { // Arrange var mock = Mock.Of(); - mock.Setup.BuildQuery( + mock.BuildQuery( "users", Arg.Any(), Arg.Is(w => w != null && w.Contains("active")), @@ -258,7 +258,7 @@ public async Task Payment_Method_With_CancellationToken_And_Nullable() { // Arrange var mock = Mock.Of(); - mock.Setup.ProcessPaymentAsync( + mock.ProcessPaymentAsync( "merchant-123", Arg.Is(a => a > 0), "USD", @@ -283,7 +283,7 @@ public async Task Payment_Method_With_CancellationToken_And_Nullable() await Assert.That(result).IsTrue(); // Verify the call was made - mock.Verify.ProcessPaymentAsync( + mock.ProcessPaymentAsync( "merchant-123", Arg.Any(), "USD", @@ -309,16 +309,16 @@ public async Task Deep_Interface_Inheritance_All_Properties_Accessible() // Setup properties from all three levels of inheritance // IEntity - mock.Setup.Id.Returns(42); - mock.Setup.CreatedAt.Returns(now); + mock.Id.Returns(42); + mock.CreatedAt.Returns(now); // IAuditable - mock.Setup.CreatedBy.Returns("admin"); - mock.Setup.ModifiedAt.Returns(now.AddHours(1)); - mock.Setup.ModifiedBy.Returns("editor"); + mock.CreatedBy.Returns("admin"); + mock.ModifiedAt.Returns(now.AddHours(1)); + mock.ModifiedBy.Returns("editor"); // ISoftDeletable - mock.Setup.IsDeleted.Returns(false); - mock.Setup.DeletedAt.Returns((DateTime?)null); - mock.Setup.DeletedBy.Returns((string?)null); + mock.IsDeleted.Returns(false); + mock.DeletedAt.Returns((DateTime?)null); + mock.DeletedBy.Returns((string?)null); // Act ISoftDeletable entity = mock.Object; @@ -339,15 +339,15 @@ public async Task Repository_Returning_Inherited_Interface() { // Arrange — create a mock ISoftDeletable to use as the return value var entityMock = Mock.Of(); - entityMock.Setup.Id.Returns(1); - entityMock.Setup.CreatedBy.Returns("system"); - entityMock.Setup.IsDeleted.Returns(false); + entityMock.Id.Returns(1); + entityMock.CreatedBy.Returns("system"); + entityMock.IsDeleted.Returns(false); var repoMock = Mock.Of(); - repoMock.Setup.GetByIdAsync(1).Returns(entityMock.Object); + repoMock.GetByIdAsync(1).Returns(entityMock.Object); var activeList = new List { entityMock.Object }; - repoMock.Setup.GetActiveAsync().Returns((IReadOnlyList)activeList.AsReadOnly()); + repoMock.GetActiveAsync().Returns((IReadOnlyList)activeList.AsReadOnly()); // Act IAuditRepository repo = repoMock.Object; @@ -376,7 +376,7 @@ public async Task Throws_Specific_Exception_With_Message() { // Arrange var mock = Mock.Of(); - mock.Setup.GetConfig("missing-key").Throws(); + mock.GetConfig("missing-key").Throws(); // Act & Assert IExternalApi api = mock.Object; @@ -393,7 +393,7 @@ public async Task Sequential_Throws_Then_Succeeds() { // Arrange — simulate a retry pattern: first call fails, second succeeds var mock = Mock.Of(); - mock.Setup.CallRemoteServiceAsync("https://api.example.com/data") + mock.CallRemoteServiceAsync("https://api.example.com/data") .Throws() .Then() .Returns("success"); @@ -425,7 +425,7 @@ public async Task Async_Throws_Returns_Faulted_Task_Not_Sync_Throw() { // Arrange var mock = Mock.Of(); - mock.Setup.CallRemoteServiceAsync(Arg.Any()).Throws(); + mock.CallRemoteServiceAsync(Arg.Any()).Throws(); // Act — the method should return a faulted task, NOT throw synchronously IExternalApi api = mock.Object; @@ -450,9 +450,9 @@ public async Task Different_Args_Different_Exceptions() { // Arrange var mock = Mock.Of(); - mock.Setup.GetConfig("arg-error").Throws(); - mock.Setup.GetConfig("timeout").Throws(); - mock.Setup.GetConfig("valid").Returns("value"); + mock.GetConfig("arg-error").Throws(); + mock.GetConfig("timeout").Throws(); + mock.GetConfig("valid").Returns("value"); // Act & Assert IExternalApi api = mock.Object; @@ -479,7 +479,7 @@ public async Task Predicate_Matcher_String_Length_Range() { // Arrange var mock = Mock.Of(); - mock.Setup.Validate(Arg.Is(s => s != null && s.Length >= 3 && s.Length <= 50)).Returns(true); + mock.Validate(Arg.Is(s => s != null && s.Length >= 3 && s.Length <= 50)).Returns(true); // Act IValidator validator = mock.Object; @@ -500,7 +500,7 @@ public async Task Multiple_Predicates_On_Multiple_Args() { // Arrange var mock = Mock.Of(); - mock.Setup.Score( + mock.Score( Arg.Is(t => t != null && t.Length > 0), Arg.Is(w => w >= 1 && w <= 10) ).Returns(100); @@ -524,8 +524,8 @@ public async Task Exact_Match_Overrides_Any_Match_Later_Wins() { // Arrange — setup Any first, then exact. Last setup wins for matching args. var mock = Mock.Of(); - mock.Setup.Validate(Arg.Any()).Returns(false); - mock.Setup.Validate("special").Returns(true); + mock.Validate(Arg.Any()).Returns(false); + mock.Validate("special").Returns(true); // Act IValidator validator = mock.Object; @@ -542,7 +542,7 @@ public async Task Arg_Capture_Across_Multiple_Calls_Verifies_All() // Arrange var input = Arg.Any(); var mock = Mock.Of(); - mock.Setup.Validate(input).Returns(true); + mock.Validate(input).Returns(true); // Act — 5 calls with different arguments IValidator validator = mock.Object; @@ -573,7 +573,7 @@ public async Task Reset_Then_Reconfigure_Different_Behavior() { // Arrange var mock = Mock.Of(); - mock.Setup.GetConfig("key").Returns("A"); + mock.GetConfig("key").Returns("A"); IExternalApi api = mock.Object; @@ -583,7 +583,7 @@ public async Task Reset_Then_Reconfigure_Different_Behavior() // Reset and reconfigure mock.Reset(); - mock.Setup.GetConfig("key").Returns("B"); + mock.GetConfig("key").Returns("B"); // Second phase var secondResult = api.GetConfig("key"); @@ -605,22 +605,22 @@ public async Task Reset_Mid_Test_Changes_Verification_Baseline() api.GetConfig("key1"); // Verify pre-reset state - mock.Verify.GetConfig("key1").WasCalled(Times.Exactly(2)); - mock.Verify.GetConfig("key2").WasCalled(Times.Once); + mock.GetConfig("key1").WasCalled(Times.Exactly(2)); + mock.GetConfig("key2").WasCalled(Times.Once); // Reset — clears call history mock.Reset(); // Post-reset: previous calls should not count - mock.Verify.GetConfig("key1").WasNeverCalled(); - mock.Verify.GetConfig("key2").WasNeverCalled(); + mock.GetConfig("key1").WasNeverCalled(); + mock.GetConfig("key2").WasNeverCalled(); // Make new calls api.GetConfig("key1"); // Verify only post-reset calls - mock.Verify.GetConfig("key1").WasCalled(Times.Once); - mock.Verify.GetConfig("key2").WasNeverCalled(); + mock.GetConfig("key1").WasCalled(Times.Once); + mock.GetConfig("key2").WasNeverCalled(); await Assert.That(true).IsTrue(); } } @@ -635,7 +635,7 @@ public async Task Concurrent_Setup_And_Invocation_From_Multiple_Threads() { // Arrange var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns(42); + mock.GetValue(Arg.Any()).Returns(42); IConcurrentService svc = mock.Object; // Act — 10 threads setting up and calling simultaneously @@ -643,7 +643,7 @@ public async Task Concurrent_Setup_And_Invocation_From_Multiple_Threads() { // Each thread sets up its own key and calls it var key = $"key-{i}"; - mock.Setup.GetValue(key).Returns(i); + mock.GetValue(key).Returns(i); return svc.GetValue(key); })); @@ -663,7 +663,7 @@ public async Task Concurrent_Verification_After_Parallel_Calls() { // Arrange var mock = Mock.Of(); - mock.Setup.IncrementAsync(Arg.Any()).Returns(1); + mock.IncrementAsync(Arg.Any()).Returns(1); IConcurrentService svc = mock.Object; // Act — 100 parallel calls @@ -672,7 +672,7 @@ public async Task Concurrent_Verification_After_Parallel_Calls() await Task.WhenAll(tasks); // Assert — verify exact count after all parallel calls complete - mock.Verify.IncrementAsync("counter").WasCalled(Times.Exactly(100)); + mock.IncrementAsync("counter").WasCalled(Times.Exactly(100)); await Assert.That(true).IsTrue(); } } @@ -698,8 +698,8 @@ public async Task Enum_Parameter_Exact_Match() new() { Id = 3, Title = "Another high", Priority = Priority.High, Status = Status.Active } }; - mock.Setup.GetByPriorityAsync(Priority.Low).Returns(lowItems); - mock.Setup.GetByPriorityAsync(Priority.High).Returns(highItems); + mock.GetByPriorityAsync(Priority.Low).Returns(lowItems); + mock.GetByPriorityAsync(Priority.High).Returns(highItems); // Act ITaskManager mgr = mock.Object; @@ -719,8 +719,8 @@ public async Task Enum_Parameter_With_Predicate_Matcher() { // Arrange var mock = Mock.Of(); - mock.Setup.CountByStatusAsync(Arg.Is(s => s == Status.Active || s == Status.Pending)).Returns(10); - mock.Setup.CountByStatusAsync(Arg.Is(s => s == Status.Completed || s == Status.Failed)).Returns(5); + mock.CountByStatusAsync(Arg.Is(s => s == Status.Active || s == Status.Pending)).Returns(10); + mock.CountByStatusAsync(Arg.Is(s => s == Status.Completed || s == Status.Failed)).Returns(5); // Act ITaskManager mgr = mock.Object; @@ -747,14 +747,14 @@ public async Task Enum_Void_Method_Verify_Specific_Value() mgr.UpdateStatus(3, Status.Active); // Assert — verify UpdateStatus called with specific Status values - mock.Verify.UpdateStatus(Arg.Any(), Status.Active).WasCalled(Times.Exactly(2)); - mock.Verify.UpdateStatus(Arg.Any(), Status.Completed).WasCalled(Times.Once); - mock.Verify.UpdateStatus(Arg.Any(), Status.Failed).WasNeverCalled(); - mock.Verify.UpdateStatus(Arg.Any(), Status.Pending).WasNeverCalled(); + mock.UpdateStatus(Arg.Any(), Status.Active).WasCalled(Times.Exactly(2)); + mock.UpdateStatus(Arg.Any(), Status.Completed).WasCalled(Times.Once); + mock.UpdateStatus(Arg.Any(), Status.Failed).WasNeverCalled(); + mock.UpdateStatus(Arg.Any(), Status.Pending).WasNeverCalled(); // Verify specific task ID + status combination - mock.Verify.UpdateStatus(1, Status.Active).WasCalled(Times.Once); - mock.Verify.UpdateStatus(2, Status.Completed).WasCalled(Times.Once); + mock.UpdateStatus(1, Status.Active).WasCalled(Times.Once); + mock.UpdateStatus(2, Status.Completed).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } } diff --git a/TUnit.Mocks.Tests/ErrorMessageTests.cs b/TUnit.Mocks.Tests/ErrorMessageTests.cs index 7755ffd63f..dbe833fea0 100644 --- a/TUnit.Mocks.Tests/ErrorMessageTests.cs +++ b/TUnit.Mocks.Tests/ErrorMessageTests.cs @@ -21,7 +21,7 @@ public async Task Verification_Message_Contains_Expected_Call_Description() // Act & Assert — verify a call that was never made var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Once); + mock.Add(1, 2).WasCalled(Times.Once); }); await Assert.That(exception.Message).Contains("Add"); @@ -41,7 +41,7 @@ public async Task Verification_Message_Contains_Actual_Count() // Act & Assert — expect 5 but only 3 calls made var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(5)); + mock.Add(1, 2).WasCalled(Times.Exactly(5)); }); await Assert.That(exception.ActualCount).IsEqualTo(3); @@ -59,7 +59,7 @@ public async Task Verification_Message_Contains_Formatted_Argument_Values() // Act & Assert — verify with different args that were never called var exception = Assert.Throws(() => { - mock.Verify.Add(10, 20).WasCalled(Times.Once); + mock.Add(10, 20).WasCalled(Times.Once); }); // The expected call should mention the args we verified with @@ -78,7 +78,7 @@ public async Task Verification_Message_Contains_String_Arguments() // Act & Assert — verify a call with different string arg var exception = Assert.Throws(() => { - mock.Verify.Greet("Bob").WasCalled(Times.Once); + mock.Greet("Bob").WasCalled(Times.Once); }); await Assert.That(exception.ExpectedCall).Contains("Greet"); @@ -94,7 +94,7 @@ public async Task Verification_Message_Contains_Expected_Times_Description() // Act & Assert var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(3)); + mock.Add(1, 2).WasCalled(Times.Exactly(3)); }); // The message should describe the expected call count @@ -114,7 +114,7 @@ public async Task Verification_WasNeverCalled_Message_Shows_Actual_Count() // Act & Assert — WasNeverCalled should fail since it was called twice var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasNeverCalled(); + mock.Add(1, 2).WasNeverCalled(); }); await Assert.That(exception.ActualCount).IsEqualTo(2); @@ -131,7 +131,7 @@ public async Task Verification_AtLeast_Message_Shows_Shortfall() // Act & Assert — expect at least 5 but only 1 call var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.AtLeast(5)); + mock.Add(1, 2).WasCalled(Times.AtLeast(5)); }); await Assert.That(exception.ActualCount).IsEqualTo(1); @@ -150,7 +150,7 @@ public async Task Verification_Actual_Calls_List_Is_Populated() // Act & Assert — verify with Arg.Any but wrong count var exception = Assert.Throws(() => { - mock.Verify.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(5)); + mock.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(5)); }); await Assert.That(exception.ActualCount).IsEqualTo(2); diff --git a/TUnit.Mocks.Tests/EventTests.cs b/TUnit.Mocks.Tests/EventTests.cs index 5c1c158d45..5026d21186 100644 --- a/TUnit.Mocks.Tests/EventTests.cs +++ b/TUnit.Mocks.Tests/EventTests.cs @@ -26,7 +26,7 @@ public async Task Raise_Event_Notifies_Subscriber() svc.OnMessage += (sender, msg) => receivedMessage = msg; // Act — raise the event through the mock - mock.Raise.OnMessage("Hello!"); + mock.RaiseOnMessage("Hello!"); // Assert await Assert.That(receivedMessage).IsEqualTo("Hello!"); @@ -44,7 +44,7 @@ public async Task Raise_Event_Notifies_Multiple_Subscribers() svc.OnMessage += (sender, msg) => messages.Add("sub2:" + msg); // Act - mock.Raise.OnMessage("test"); + mock.RaiseOnMessage("test"); // Assert await Assert.That(messages).Count().IsEqualTo(2); @@ -59,7 +59,7 @@ public async Task Raise_Event_With_No_Subscribers_Does_Not_Throw() var mock = Mock.Of(); // Act & Assert — should not throw when no subscribers - mock.Raise.OnMessage("nobody listening"); + mock.RaiseOnMessage("nobody listening"); await Assert.That(true).IsTrue(); } @@ -75,9 +75,9 @@ public async Task Unsubscribe_From_Event_Stops_Notifications() svc.OnMessage += handler; // Act — raise once, unsubscribe, raise again - mock.Raise.OnMessage("first"); + mock.RaiseOnMessage("first"); svc.OnMessage -= handler; - mock.Raise.OnMessage("second"); + mock.RaiseOnMessage("second"); // Assert — only one notification await Assert.That(callCount).IsEqualTo(1); diff --git a/TUnit.Mocks.Tests/GenericTests.cs b/TUnit.Mocks.Tests/GenericTests.cs index 6054b92c5d..c05e4717c3 100644 --- a/TUnit.Mocks.Tests/GenericTests.cs +++ b/TUnit.Mocks.Tests/GenericTests.cs @@ -35,7 +35,7 @@ public async Task Generic_Method_Returns_Configured_Value() // Arrange var mock = Mock.Of(); var customer = new Customer { Id = 1, Name = "Alice" }; - mock.Setup.Get(1).Returns(customer); + mock.Get(1).Returns(customer); // Act IRepository repo = mock.Object; @@ -68,8 +68,8 @@ public async Task Generic_Method_Different_Type_Arguments() var customer = new Customer { Id = 1, Name = "Alice" }; var order = new Order { OrderId = 42 }; - mock.Setup.Get(1).Returns(customer); - mock.Setup.Get(2).Returns(order); + mock.Get(1).Returns(customer); + mock.Get(2).Returns(order); // Act IRepository repo = mock.Object; @@ -107,7 +107,7 @@ public async Task Generic_Void_Method_Verify() repo.Save(customer); // Assert - mock.Verify.Save(Arg.Any()).WasCalled(Times.Once); + mock.Save(Arg.Any()).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -117,7 +117,7 @@ public async Task Generic_Method_With_Any_Matcher() // Arrange var mock = Mock.Of(); var customer = new Customer { Id = 1, Name = "Any" }; - mock.Setup.Get(Arg.Any()).Returns(customer); + mock.Get(Arg.Any()).Returns(customer); // Act IRepository repo = mock.Object; @@ -135,7 +135,7 @@ public async Task Generic_Method_With_Two_Type_Parameters() // Arrange var mock = Mock.Of(); var order = new Order { OrderId = 10 }; - mock.Setup.Transform(Arg.Any()).Returns(order); + mock.Transform(Arg.Any()).Returns(order); // Act IRepository repo = mock.Object; diff --git a/TUnit.Mocks.Tests/InvocationsTests.cs b/TUnit.Mocks.Tests/InvocationsTests.cs index 25a84a90ce..f399c6311b 100644 --- a/TUnit.Mocks.Tests/InvocationsTests.cs +++ b/TUnit.Mocks.Tests/InvocationsTests.cs @@ -12,7 +12,7 @@ public interface IService public async Task Invocations_Returns_All_Calls() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("key1"); @@ -26,7 +26,7 @@ public async Task Invocations_Returns_All_Calls() public async Task Invocations_Contains_Correct_Method_Names() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("key1"); @@ -40,7 +40,7 @@ public async Task Invocations_Contains_Correct_Method_Names() public async Task Invocations_Contains_Correct_Arguments() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("hello"); @@ -59,7 +59,7 @@ public async Task Invocations_Is_Empty_When_No_Calls_Made() public async Task Invocations_Is_Empty_After_Reset() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("key1"); diff --git a/TUnit.Mocks.Tests/MatcherTests.cs b/TUnit.Mocks.Tests/MatcherTests.cs index e5f40b68bc..12c4932416 100644 --- a/TUnit.Mocks.Tests/MatcherTests.cs +++ b/TUnit.Mocks.Tests/MatcherTests.cs @@ -13,7 +13,7 @@ public async Task InRange_MatchesWithinBounds() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.IsInRange(1, 10), Arg.Any()).Returns(99); + mock.Add(Arg.IsInRange(1, 10), Arg.Any()).Returns(99); // Act ICalculator calc = mock.Object; @@ -29,7 +29,7 @@ public async Task InRange_RejectsOutsideBounds() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.IsInRange(1, 10), Arg.Any()).Returns(99); + mock.Add(Arg.IsInRange(1, 10), Arg.Any()).Returns(99); // Act ICalculator calc = mock.Object; @@ -46,7 +46,7 @@ public async Task IsIn_MatchesSetMembers() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.IsIn(1, 3, 5), Arg.Any()).Returns(77); + mock.Add(Arg.IsIn(1, 3, 5), Arg.Any()).Returns(77); // Act ICalculator calc = mock.Object; @@ -62,7 +62,7 @@ public async Task IsIn_RejectsNonMembers() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.IsIn(1, 3, 5), Arg.Any()).Returns(77); + mock.Add(Arg.IsIn(1, 3, 5), Arg.Any()).Returns(77); // Act ICalculator calc = mock.Object; @@ -79,7 +79,7 @@ public async Task IsNotIn_MatchesNonMembers() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.IsNotIn(1, 3, 5), Arg.Any()).Returns(88); + mock.Add(Arg.IsNotIn(1, 3, 5), Arg.Any()).Returns(88); // Act ICalculator calc = mock.Object; @@ -96,7 +96,7 @@ public async Task IsNotIn_RejectsSetMembers() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.IsNotIn(1, 3, 5), Arg.Any()).Returns(88); + mock.Add(Arg.IsNotIn(1, 3, 5), Arg.Any()).Returns(88); // Act ICalculator calc = mock.Object; @@ -112,7 +112,7 @@ public async Task Not_NegatesInnerMatcher() { // Arrange — Not(Is(5)) should match everything except 5 var mock = Mock.Of(); - mock.Setup.Add(Arg.Not(Arg.Is(5)), Arg.Any()).Returns(66); + mock.Add(Arg.Not(Arg.Is(5)), Arg.Any()).Returns(66); // Act ICalculator calc = mock.Object; @@ -129,7 +129,7 @@ public async Task Not_WithPredicateMatcher() { // Arrange — Not(Is(x => x > 0)) should match non-positive values var mock = Mock.Of(); - mock.Setup.Add(Arg.Not(Arg.Is(x => x > 0)), Arg.Any()).Returns(55); + mock.Add(Arg.Not(Arg.Is(x => x > 0)), Arg.Any()).Returns(55); // Act ICalculator calc = mock.Object; diff --git a/TUnit.Mocks.Tests/MockRepositoryTests.cs b/TUnit.Mocks.Tests/MockRepositoryTests.cs index 55461c9865..61b238edd4 100644 --- a/TUnit.Mocks.Tests/MockRepositoryTests.cs +++ b/TUnit.Mocks.Tests/MockRepositoryTests.cs @@ -48,8 +48,8 @@ public async Task Repository_VerifyAll_Passes_When_All_Setups_Invoked() var serviceMock = repo.Of(); var loggerMock = repo.Of(); - serviceMock.Setup.GetData(Arg.Any()).Returns("result"); - loggerMock.Setup.Log(Arg.Any()); + serviceMock.GetData(Arg.Any()).Returns("result"); + loggerMock.Log(Arg.Any()); // Act — invoke all setups serviceMock.Object.GetData(1); @@ -67,8 +67,8 @@ public async Task Repository_VerifyAll_Throws_When_Setup_Not_Invoked() var serviceMock = repo.Of(); var loggerMock = repo.Of(); - serviceMock.Setup.GetData(Arg.Any()).Returns("result"); - loggerMock.Setup.Log(Arg.Any()); + serviceMock.GetData(Arg.Any()).Returns("result"); + loggerMock.Log(Arg.Any()); // Act — only invoke one mock's setup serviceMock.Object.GetData(1); @@ -93,8 +93,8 @@ public async Task Repository_VerifyNoOtherCalls_Passes_When_All_Verified() loggerMock.Object.Log("hello"); // Verify each call - serviceMock.Verify!.GetData(Arg.Is(1)).WasCalled(); - loggerMock.Verify!.Log(Arg.Is("hello")).WasCalled(); + serviceMock.GetData(Arg.Is(1)).WasCalled(); + loggerMock.Log(Arg.Is("hello")).WasCalled(); // Assert — no unverified calls repo.VerifyNoOtherCalls(); @@ -113,7 +113,7 @@ public async Task Repository_VerifyNoOtherCalls_Throws_When_Unverified_Calls_Exi loggerMock.Object.Log("hello"); // Only verify one mock - serviceMock.Verify!.GetData(Arg.Is(1)).WasCalled(); + serviceMock.GetData(Arg.Is(1)).WasCalled(); // Assert — loggerMock has unverified calls var ex = Assert.Throws(() => repo.VerifyNoOtherCalls()); @@ -129,7 +129,7 @@ public async Task Repository_Reset_Clears_All_Mocks() var serviceMock = repo.Of(); var loggerMock = repo.Of(); - serviceMock.Setup.GetData(Arg.Any()).Returns("configured"); + serviceMock.GetData(Arg.Any()).Returns("configured"); loggerMock.Object.Log("call before reset"); // Act @@ -223,7 +223,7 @@ public async Task Repository_OfPartial_Configured_Method_Returns_Mock_Value() // Arrange var repo = new MockRepository(); var mock = repo.OfPartial(); - mock.Setup.Greet(Arg.Any()).Returns("Mocked!"); + mock.Greet(Arg.Any()).Returns("Mocked!"); // Act var result = mock.Object.Greet("World"); @@ -238,7 +238,7 @@ public async Task Repository_OfPartial_With_Constructor_Args() // Arrange var repo = new MockRepository(); var mock = repo.OfPartial("PREFIX"); - mock.Setup.Format(Arg.Any()).Returns("formatted"); + mock.Format(Arg.Any()).Returns("formatted"); // Act — GetPrefix is virtual, unconfigured → calls base var prefix = mock.Object.GetPrefix(); @@ -255,8 +255,8 @@ public async Task Repository_OfPartial_VerifyAll_Includes_Partial_Mocks() var serviceMock = repo.Of(); var partialMock = repo.OfPartial(); - serviceMock.Setup.GetData(Arg.Any()).Returns("data"); - partialMock.Setup.Greet(Arg.Any()).Returns("Hi"); + serviceMock.GetData(Arg.Any()).Returns("data"); + partialMock.Greet(Arg.Any()).Returns("Hi"); // Act — invoke both setups serviceMock.Object.GetData(1); diff --git a/TUnit.Mocks.Tests/MultipleInterfaceTests.cs b/TUnit.Mocks.Tests/MultipleInterfaceTests.cs index 4a0e09e282..06894335c5 100644 --- a/TUnit.Mocks.Tests/MultipleInterfaceTests.cs +++ b/TUnit.Mocks.Tests/MultipleInterfaceTests.cs @@ -52,14 +52,14 @@ public async Task Can_Setup_Methods_From_Primary_Interface() { // Arrange var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()); + mock.Log(Arg.Any()); // Act var logger = mock.Object; logger.Log("test message"); // Assert — call recorded and verifiable - mock.Verify.Log(Arg.Is("test message")).WasCalled(); + mock.Log(Arg.Is("test message")).WasCalled(); } [Test] @@ -107,7 +107,7 @@ public async Task Multi_Mock_Shares_Single_Engine() { // Arrange var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()); + mock.Log(Arg.Any()); // Act — call primary and secondary interface methods mock.Object.Log("hello"); @@ -135,13 +135,13 @@ public async Task Mock_Of_Four_Interfaces_Can_Use_Primary() { // Arrange var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()); + mock.Log(Arg.Any()); // Act mock.Object.Log("hello from four-interface mock"); // Assert - mock.Verify.Log("hello from four-interface mock").WasCalled(Times.Once); + mock.Log("hello from four-interface mock").WasCalled(Times.Once); await Assert.That(true).IsTrue(); } diff --git a/TUnit.Mocks.Tests/OrderedVerificationTests.cs b/TUnit.Mocks.Tests/OrderedVerificationTests.cs index 17e9981ea2..7db7410248 100644 --- a/TUnit.Mocks.Tests/OrderedVerificationTests.cs +++ b/TUnit.Mocks.Tests/OrderedVerificationTests.cs @@ -22,8 +22,8 @@ public void Correct_Order_Passes() // Assert — verifying in the same order they were called should pass Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.GetName().WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.GetName().WasCalled(); }); } @@ -43,8 +43,8 @@ public async Task Wrong_Order_Fails_With_Message() { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.GetName().WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.GetName().WasCalled(); }); }); @@ -68,9 +68,9 @@ public void Cross_Mock_Ordering_Passes_When_Correct() // Assert — verify the cross-mock order Mock.VerifyInOrder(() => { - calcMock.Verify.Add(1, 2).WasCalled(); - greeterMock.Verify.Greet("Alice").WasCalled(); - calcMock.Verify.GetName().WasCalled(); + calcMock.Add(1, 2).WasCalled(); + greeterMock.Greet("Alice").WasCalled(); + calcMock.GetName().WasCalled(); }); } @@ -92,8 +92,8 @@ public async Task Cross_Mock_Ordering_Fails_When_Wrong() { Mock.VerifyInOrder(() => { - calcMock.Verify.Add(1, 2).WasCalled(); - greeterMock.Verify.Greet("Alice").WasCalled(); + calcMock.Add(1, 2).WasCalled(); + greeterMock.Greet("Alice").WasCalled(); }); }); @@ -113,7 +113,7 @@ public void Single_Call_In_Ordered_Verification_Passes() // Assert — single call trivially passes Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); + mock.Add(1, 2).WasCalled(); }); } @@ -133,8 +133,8 @@ public async Task Error_Message_Describes_Expected_Vs_Actual_Order() { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.Log("hello").WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.Log("hello").WasCalled(); }); }); @@ -170,8 +170,8 @@ public async Task Missing_Call_Fails_With_Descriptive_Message() { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.GetName().WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.GetName().WasCalled(); }); }); @@ -192,8 +192,8 @@ public void Multiple_Calls_Same_Method_Correct_Order() // Assert — verify both in order Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.Add(3, 4).WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.Add(3, 4).WasCalled(); }); } @@ -213,8 +213,8 @@ public async Task Multiple_Calls_Same_Method_Wrong_Order() { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.Add(3, 4).WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.Add(3, 4).WasCalled(); }); }); @@ -236,8 +236,8 @@ public void VerifyInOrder_With_Times_Exactly_Multiple() // Assert — verify Add was called exactly 3 times, then GetName once Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(3)); - mock.Verify.GetName().WasCalled(Times.Once); + mock.Add(1, 2).WasCalled(Times.Exactly(3)); + mock.GetName().WasCalled(Times.Once); }); } @@ -254,7 +254,7 @@ public async Task VerifyInOrder_With_Times_Never_Throws_InvalidOperationExceptio { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Never); + mock.Add(1, 2).WasCalled(Times.Never); }); }); @@ -274,7 +274,7 @@ public async Task VerifyInOrder_With_Times_AtMost_Throws_InvalidOperationExcepti { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(Times.AtMost(3)); + mock.Add(1, 2).WasCalled(Times.AtMost(3)); }); }); @@ -294,7 +294,7 @@ public async Task VerifyInOrder_With_Times_Between_Zero_Min_Throws_InvalidOperat { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Between(0, 3)); + mock.Add(1, 2).WasCalled(Times.Between(0, 3)); }); }); @@ -316,8 +316,8 @@ public void VerifyInOrder_With_Times_AtLeast_Passes() // Assert — verify Add was called at least 2 times (actual: 3), then GetName Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(Times.AtLeast(2)); - mock.Verify.GetName().WasCalled(); + mock.Add(1, 2).WasCalled(Times.AtLeast(2)); + mock.GetName().WasCalled(); }); } @@ -335,8 +335,8 @@ public void VerifyInOrder_Marks_Calls_As_Verified_For_VerifyNoOtherCalls() // Assert — VerifyInOrder should mark calls as verified Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.GetName().WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.GetName().WasCalled(); }); // This should pass because the calls above were verified in VerifyInOrder @@ -358,8 +358,8 @@ public async Task VerifyInOrder_Partial_Verification_Leaves_Unverified_Calls() // Assert — only verify first two in order Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(); - mock.Verify.GetName().WasCalled(); + mock.Add(1, 2).WasCalled(); + mock.GetName().WasCalled(); }); // Log("hello") was not verified, so this should fail @@ -389,8 +389,8 @@ public void VerifyInOrder_Interleaved_Multi_Call_Correct_Group_Order() { Mock.VerifyInOrder(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(2)); - mock.Verify.GetName().WasCalled(); + mock.Add(1, 2).WasCalled(Times.Exactly(2)); + mock.GetName().WasCalled(); }); }); } diff --git a/TUnit.Mocks.Tests/OutRefAssignmentTests.cs b/TUnit.Mocks.Tests/OutRefAssignmentTests.cs index 2846aeaf45..a8a9eb93e1 100644 --- a/TUnit.Mocks.Tests/OutRefAssignmentTests.cs +++ b/TUnit.Mocks.Tests/OutRefAssignmentTests.cs @@ -4,18 +4,18 @@ namespace TUnit.Mocks.Tests; /// -/// Tests for out/ref parameter value assignment via SetsOutParameter. +/// Tests for out/ref parameter value assignment via typed and untyped APIs. /// public class OutRefAssignmentTests { [Test] - public async Task Out_Parameter_Can_Be_Set_Via_Setup() + public async Task Out_Parameter_Can_Be_Set_Via_Typed_Api() { // Arrange var mock = Mock.Of(); - mock.Setup.TryGet("found") + mock.TryGet("found") .Returns(true) - .SetsOutParameter(1, "found-value"); + .SetsOutValue("found-value"); IDictionary dict = mock.Object; @@ -32,7 +32,7 @@ public async Task Out_Parameter_Stays_Default_Without_Assignment() { // Arrange var mock = Mock.Of(); - mock.Setup.TryGet("key").Returns(false); + mock.TryGet("key").Returns(false); IDictionary dict = mock.Object; @@ -45,13 +45,13 @@ public async Task Out_Parameter_Stays_Default_Without_Assignment() } [Test] - public async Task Out_Parameter_Int_Can_Be_Set() + public async Task Out_Parameter_Int_Can_Be_Set_Via_Typed_Api() { // Arrange var mock = Mock.Of(); - mock.Setup.TryParse(Arg.Any()) + mock.TryParse(Arg.Any()) .Returns(true) - .SetsOutParameter(1, 42); + .SetsOutResult(42); IDictionary dict = mock.Object; @@ -64,13 +64,13 @@ public async Task Out_Parameter_Int_Can_Be_Set() } [Test] - public async Task Out_Parameter_With_Any_Matcher() + public async Task Out_Parameter_With_Any_Matcher_Via_Typed_Api() { // Arrange var mock = Mock.Of(); - mock.Setup.TryGet(Arg.Any()) + mock.TryGet(Arg.Any()) .Returns(true) - .SetsOutParameter(1, "any-value"); + .SetsOutValue("any-value"); IDictionary dict = mock.Object; @@ -84,12 +84,12 @@ public async Task Out_Parameter_With_Any_Matcher() } [Test] - public async Task Ref_Parameter_Can_Be_Set_Via_Setup() + public async Task Ref_Parameter_Can_Be_Set_Via_Typed_Api() { // Arrange var mock = Mock.Of(); - mock.Setup.Swap(Arg.Any()) - .SetsOutParameter(0, 99); + mock.Swap(Arg.Any()) + .SetsRefValue(99); IDictionary dict = mock.Object; @@ -100,4 +100,42 @@ public async Task Ref_Parameter_Can_Be_Set_Via_Setup() // Assert await Assert.That(val).IsEqualTo(99); } + + [Test] + public async Task Untyped_SetsOutParameter_Still_Works() + { + // Arrange — backward compatibility with untyped API + var mock = Mock.Of(); + mock.TryGet("key") + .Returns(true) + .SetsOutParameter(1, "untyped-value"); + + IDictionary dict = mock.Object; + + // Act + var success = dict.TryGet("key", out var value); + + // Assert + await Assert.That(success).IsTrue(); + await Assert.That(value).IsEqualTo("untyped-value"); + } + + [Test] + public async Task Typed_And_Chaining_Works() + { + // Arrange — chain typed out/ref setter with Returns + var mock = Mock.Of(); + mock.TryGet(Arg.Any()) + .SetsOutValue("chained") + .Returns(true); + + IDictionary dict = mock.Object; + + // Act + var success = dict.TryGet("x", out var value); + + // Assert + await Assert.That(success).IsTrue(); + await Assert.That(value).IsEqualTo("chained"); + } } diff --git a/TUnit.Mocks.Tests/OutRefTests.cs b/TUnit.Mocks.Tests/OutRefTests.cs index e6ddffb1ad..24abcd2bfb 100644 --- a/TUnit.Mocks.Tests/OutRefTests.cs +++ b/TUnit.Mocks.Tests/OutRefTests.cs @@ -43,7 +43,7 @@ public async Task Out_Parameter_Method_Verify_Call_Was_Made() dict.TryGet("hello", out _); // Assert - verify with the input arg only (out param excluded from matchers) - mock.Verify.TryGet("hello").WasCalled(Times.Once); + mock.TryGet("hello").WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -52,7 +52,7 @@ public async Task Out_Parameter_Method_Setup_Return_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.TryGet("found").Returns(true); + mock.TryGet("found").Returns(true); // Act IDictionary dict = mock.Object; @@ -67,7 +67,7 @@ public async Task Out_Parameter_Method_With_Any_Matcher() { // Arrange var mock = Mock.Of(); - mock.Setup.TryGet(Arg.Any()).Returns(true); + mock.TryGet(Arg.Any()).Returns(true); // Act IDictionary dict = mock.Object; @@ -101,7 +101,7 @@ public async Task Out_Parameter_Method_Verify_Never_Called() var mock = Mock.Of(); // Assert - never called - mock.Verify.TryGet("key").WasNeverCalled(); + mock.TryGet("key").WasNeverCalled(); await Assert.That(true).IsTrue(); } @@ -133,7 +133,7 @@ public async Task Ref_Parameter_Method_Verify_Call() dict.Swap(ref val); // Assert - ref params ARE included in matchers - mock.Verify.Swap(10).WasCalled(Times.Once); + mock.Swap(10).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -150,8 +150,8 @@ public async Task Multiple_Out_Method_Calls_Tracked() dict.TryGet("a", out _); // Assert - mock.Verify.TryGet("a").WasCalled(Times.Exactly(2)); - mock.Verify.TryGet("b").WasCalled(Times.Once); + mock.TryGet("a").WasCalled(Times.Exactly(2)); + mock.TryGet("b").WasCalled(Times.Once); await Assert.That(true).IsTrue(); } } diff --git a/TUnit.Mocks.Tests/PartialMockTests.cs b/TUnit.Mocks.Tests/PartialMockTests.cs index cc96e1a735..0ed6d333e1 100644 --- a/TUnit.Mocks.Tests/PartialMockTests.cs +++ b/TUnit.Mocks.Tests/PartialMockTests.cs @@ -55,7 +55,7 @@ public async Task Abstract_Method_Returns_Configured_Value() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("TestName"); + mock.GetName().Returns("TestName"); // Act var result = mock.Object.GetName(); @@ -70,7 +70,7 @@ public async Task Unconfigured_Virtual_Method_Calls_Base_Implementation() // Arrange var mock = Mock.OfPartial(); // GetName is abstract - configure it - mock.Setup.GetName().Returns("TestName"); + mock.GetName().Returns("TestName"); // Calculate is virtual - do NOT configure it // Act @@ -85,8 +85,8 @@ public async Task Configured_Virtual_Method_Returns_Override_Instead_Of_Base() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("TestName"); - mock.Setup.Calculate(Arg.Any()).Returns(42); + mock.GetName().Returns("TestName"); + mock.Calculate(Arg.Any()).Returns(42); // Act var result = mock.Object.Calculate(5); @@ -113,7 +113,7 @@ public async Task Concrete_Class_Override_Returns_Configured_Value() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.Greet(Arg.Any()).Returns("Mocked!"); + mock.Greet(Arg.Any()).Returns("Mocked!"); // Act var result = mock.Object.Greet("World"); @@ -127,7 +127,7 @@ public async Task Concrete_Class_Multiple_Methods_Mixed_Setup() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.Greet("Alice").Returns("Hi Alice!"); + mock.Greet("Alice").Returns("Hi Alice!"); // Don't setup Add - let it call base // Act @@ -144,7 +144,7 @@ public async Task Constructor_Args_Passed_To_Base() { // Arrange var mock = Mock.OfPartial("PREFIX"); - mock.Setup.Format(Arg.Any()).Returns("formatted"); + mock.Format(Arg.Any()).Returns("formatted"); // Act - GetPrefix is virtual and unconfigured, so calls base which uses _prefix var prefix = mock.Object.GetPrefix(); @@ -158,7 +158,7 @@ public async Task Constructor_Args_Abstract_Method_Override() { // Arrange var mock = Mock.OfPartial("test"); - mock.Setup.Format("value").Returns("test:value"); + mock.Format("value").Returns("test:value"); // Act var result = mock.Object.Format("value"); @@ -172,7 +172,7 @@ public async Task Non_Virtual_Method_Still_Works() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("Name"); + mock.GetName().Returns("Name"); // Act - NonVirtualMethod is not virtual, so it runs the original implementation var result = mock.Object.NonVirtualMethod(); @@ -186,14 +186,14 @@ public void Verify_Calls_On_Partial_Mock() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.Greet(Arg.Any()).Returns("Hi"); + mock.Greet(Arg.Any()).Returns("Hi"); // Act mock.Object.Greet("Alice"); mock.Object.Greet("Bob"); // Assert - mock.Verify.Greet(Arg.Any()).WasCalled(Times.Exactly(2)); + mock.Greet(Arg.Any()).WasCalled(Times.Exactly(2)); } [Test] @@ -207,7 +207,7 @@ public void Verify_Calls_On_Unconfigured_Virtual_Method() mock.Object.Add(3, 4); // Assert - calls should still be recorded even when calling base - mock.Verify.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(2)); + mock.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(2)); } [Test] diff --git a/TUnit.Mocks.Tests/PropertyTests.cs b/TUnit.Mocks.Tests/PropertyTests.cs index 3077d2834d..959d63a901 100644 --- a/TUnit.Mocks.Tests/PropertyTests.cs +++ b/TUnit.Mocks.Tests/PropertyTests.cs @@ -41,7 +41,7 @@ public async Task Getter_Returns_Configured_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.Name.Returns("TestName"); + mock.Name.Returns("TestName"); // Act IPropertyService svc = mock.Object; @@ -56,7 +56,7 @@ public async Task Getter_Returns_Configured_Int_Value() { // Arrange var mock = Mock.Of(); - mock.Setup.Count.Returns(42); + mock.Count.Returns(42); // Act IPropertyService svc = mock.Object; @@ -77,7 +77,7 @@ public async Task Setter_Records_Call() svc.Count = 10; // Assert — verify setter was called - mock.Verify.Count.Set(10).WasCalled(Times.Once); + mock.Count.Set(10).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -94,7 +94,7 @@ public async Task Setter_Verify_With_Any_Matcher() svc.Count = 15; // Assert — verify setter was called 3 times with any value - mock.Verify.Count.Setter.WasCalled(Times.Exactly(3)); + mock.Count.Setter.WasCalled(Times.Exactly(3)); await Assert.That(true).IsTrue(); } @@ -110,8 +110,8 @@ public async Task Setter_Verify_With_Specific_Value() svc.Count = 10; // Assert — only one call with value 10 - mock.Verify.Count.Set(10).WasCalled(Times.Once); - mock.Verify.Count.Set(5).WasCalled(Times.Once); + mock.Count.Set(10).WasCalled(Times.Once); + mock.Count.Set(5).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -124,7 +124,7 @@ public async Task Setter_Verify_Never_Called() // Act — don't set anything // Assert - mock.Verify.Count.Setter.WasNeverCalled(); + mock.Count.Setter.WasNeverCalled(); await Assert.That(true).IsTrue(); } @@ -140,7 +140,7 @@ public async Task Getter_Verify_Was_Called() _ = svc.Name; // Assert — getter was called twice - mock.Verify.Name.WasCalled(Times.Exactly(2)); + mock.Name.WasCalled(Times.Exactly(2)); await Assert.That(true).IsTrue(); } @@ -153,7 +153,7 @@ public async Task Getter_Verify_Never_Called() // Act — don't access the property // Assert - mock.Verify.Name.WasNeverCalled(); + mock.Name.WasNeverCalled(); await Assert.That(true).IsTrue(); } @@ -176,8 +176,8 @@ public async Task Multiple_Getter_Setups_Last_Wins() { // Arrange var mock = Mock.Of(); - mock.Setup.Name.Returns("First"); - mock.Setup.Name.Returns("Second"); + mock.Name.Returns("First"); + mock.Name.Returns("Second"); // Act IPropertyService svc = mock.Object; @@ -194,7 +194,7 @@ public async Task Setter_Setup_Callback() var mock = Mock.Of(); var callbackCalled = false; Action callback = () => callbackCalled = true; - mock.Setup.Count.Set(Arg.Any()).Callback(callback); + mock.Count.Set(Arg.Any()).Callback(callback); // Act IPropertyService svc = mock.Object; diff --git a/TUnit.Mocks.Tests/ProtectedMemberTests.cs b/TUnit.Mocks.Tests/ProtectedMemberTests.cs index f1430d2ade..bfa0833fa9 100644 --- a/TUnit.Mocks.Tests/ProtectedMemberTests.cs +++ b/TUnit.Mocks.Tests/ProtectedMemberTests.cs @@ -33,14 +33,14 @@ public async Task Protected_Virtual_Method_Calls_Base_When_Not_Configured() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("Test"); - mock.Setup.FormatResult(Arg.Any()).Returns("formatted"); + mock.GetName().Returns("Test"); + mock.FormatResult(Arg.Any()).Returns("formatted"); // Act — ComputeValue is protected virtual, not configured → calls base (input * 2) var result = mock.Object.ProcessAndFormat(5); // Assert — FormatResult receives 10 (5 * 2 from base ComputeValue) - mock.Verify!.FormatResult(Arg.Is(10)).WasCalled(); + mock.FormatResult(Arg.Is(10)).WasCalled(); await Assert.That(result).IsEqualTo("formatted"); } @@ -49,15 +49,15 @@ public async Task Protected_Virtual_Method_Can_Be_Configured() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("Test"); - mock.Setup.ComputeValue(Arg.Any()).Returns(42); - mock.Setup.FormatResult(Arg.Any()).Returns("configured"); + mock.GetName().Returns("Test"); + mock.ComputeValue(Arg.Any()).Returns(42); + mock.FormatResult(Arg.Any()).Returns("configured"); // Act — ComputeValue is configured to return 42 var result = mock.Object.ProcessAndFormat(5); // Assert — FormatResult receives 42 (from configured ComputeValue) - mock.Verify!.FormatResult(Arg.Is(42)).WasCalled(); + mock.FormatResult(Arg.Is(42)).WasCalled(); await Assert.That(result).IsEqualTo("configured"); } @@ -66,8 +66,8 @@ public async Task Protected_Abstract_Method_Can_Be_Configured() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("Test"); - mock.Setup.FormatResult(Arg.Any()).Returns("custom format"); + mock.GetName().Returns("Test"); + mock.FormatResult(Arg.Any()).Returns("custom format"); // Act var result = mock.Object.ProcessAndFormat(3); @@ -81,8 +81,8 @@ public async Task Protected_Method_Calls_Are_Recorded_In_Invocations() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("Test"); - mock.Setup.FormatResult(Arg.Any()).Returns("result"); + mock.GetName().Returns("Test"); + mock.FormatResult(Arg.Any()).Returns("result"); // Act mock.Object.ProcessAndFormat(7); @@ -96,14 +96,14 @@ public async Task Protected_Method_Can_Be_Verified() { // Arrange var mock = Mock.OfPartial(); - mock.Setup.GetName().Returns("Test"); - mock.Setup.FormatResult(Arg.Any()).Returns("result"); + mock.GetName().Returns("Test"); + mock.FormatResult(Arg.Any()).Returns("result"); // Act mock.Object.ProcessAndFormat(5); // Assert — verify protected methods were called - mock.Verify!.ComputeValue(Arg.Is(5)).WasCalled(); - mock.Verify!.FormatResult(Arg.Any()).WasCalled(); + mock.ComputeValue(Arg.Is(5)).WasCalled(); + mock.FormatResult(Arg.Any()).WasCalled(); } } diff --git a/TUnit.Mocks.Tests/RealWorldScenarioTests.cs b/TUnit.Mocks.Tests/RealWorldScenarioTests.cs index 80a43d0679..60f3c6818d 100644 --- a/TUnit.Mocks.Tests/RealWorldScenarioTests.cs +++ b/TUnit.Mocks.Tests/RealWorldScenarioTests.cs @@ -149,9 +149,9 @@ public async Task Repository_CRUD_Full_Lifecycle() var mock = Mock.Of(); var user = new UserDto { Id = 1, Name = "Alice", Email = "alice@example.com" }; - mock.Setup.CreateAsync(Arg.Any()).Returns(user); - mock.Setup.GetByIdAsync(1).Returns(user); - mock.Setup.ExistsAsync(1).Returns(true); + mock.CreateAsync(Arg.Any()).Returns(user); + mock.GetByIdAsync(1).Returns(user); + mock.ExistsAsync(1).Returns(true); IUserRepository repo = mock.Object; @@ -173,10 +173,10 @@ public async Task Repository_CRUD_Full_Lifecycle() await Assert.That(exists).IsTrue(); // Verify all calls - mock.Verify.CreateAsync(Arg.Any()).WasCalled(Times.Once); - mock.Verify.GetByIdAsync(1).WasCalled(Times.Once); - mock.Verify.UpdateAsync(Arg.Any()).WasCalled(Times.Once); - mock.Verify.ExistsAsync(1).WasCalled(Times.Once); + mock.CreateAsync(Arg.Any()).WasCalled(Times.Once); + mock.GetByIdAsync(1).WasCalled(Times.Once); + mock.UpdateAsync(Arg.Any()).WasCalled(Times.Once); + mock.ExistsAsync(1).WasCalled(Times.Once); } [Test] @@ -189,7 +189,7 @@ public async Task Repository_With_CancellationToken_Default_Parameter() new() { Id = 1, Name = "Alice Smith", Email = "alice@example.com" }, new() { Id = 2, Name = "Alice Jones", Email = "alicej@example.com" }, }; - mock.Setup.FindByNameAsync("Alice", Arg.Any()) + mock.FindByNameAsync("Alice", Arg.Any()) .Returns((IReadOnlyList)users); IUserRepository repo = mock.Object; @@ -202,7 +202,7 @@ public async Task Repository_With_CancellationToken_Default_Parameter() await Assert.That(result[0].Name).IsEqualTo("Alice Smith"); // Verify - mock.Verify.FindByNameAsync("Alice", Arg.Any()).WasCalled(Times.Once); + mock.FindByNameAsync("Alice", Arg.Any()).WasCalled(Times.Once); } [Test] @@ -211,7 +211,7 @@ public async Task UnitOfWork_Transaction_Commit_Flow() // Arrange var mockTx = Mock.Of(); var mockUow = Mock.Of(); - mockUow.Setup.BeginTransactionAsync().Returns(mockTx.Object); + mockUow.BeginTransactionAsync().Returns(mockTx.Object); IUnitOfWork uow = mockUow.Object; @@ -221,10 +221,10 @@ public async Task UnitOfWork_Transaction_Commit_Flow() await tx.CommitAsync(); // Assert - mockUow.Verify.BeginTransactionAsync().WasCalled(Times.Once); - mockUow.Verify.SaveChangesAsync(Arg.Any()).WasCalled(Times.Once); - mockTx.Verify.CommitAsync().WasCalled(Times.Once); - mockTx.Verify.RollbackAsync().WasNeverCalled(); + mockUow.BeginTransactionAsync().WasCalled(Times.Once); + mockUow.SaveChangesAsync(Arg.Any()).WasCalled(Times.Once); + mockTx.CommitAsync().WasCalled(Times.Once); + mockTx.RollbackAsync().WasNeverCalled(); } [Test] @@ -233,8 +233,8 @@ public async Task UnitOfWork_Transaction_Rollback_On_Exception() // Arrange var mockTx = Mock.Of(); var mockUow = Mock.Of(); - mockUow.Setup.BeginTransactionAsync().Returns(mockTx.Object); - mockUow.Setup.SaveChangesAsync(Arg.Any()) + mockUow.BeginTransactionAsync().Returns(mockTx.Object); + mockUow.SaveChangesAsync(Arg.Any()) .Throws(); IUnitOfWork uow = mockUow.Object; @@ -251,8 +251,8 @@ public async Task UnitOfWork_Transaction_Rollback_On_Exception() } // Assert — rollback was called, commit was not - mockTx.Verify.RollbackAsync().WasCalled(Times.Once); - mockTx.Verify.CommitAsync().WasNeverCalled(); + mockTx.RollbackAsync().WasCalled(Times.Once); + mockTx.CommitAsync().WasNeverCalled(); } [Test] @@ -260,7 +260,7 @@ public async Task Repository_Returns_Null_For_NotFound() { // Arrange var mock = Mock.Of(); - mock.Setup.GetByIdAsync(999).Returns((UserDto?)null); + mock.GetByIdAsync(999).Returns((UserDto?)null); IUserRepository repo = mock.Object; @@ -284,7 +284,7 @@ public async Task Multiple_Mocks_Injected_Into_Service_Orchestration() var mockLogger = Mock.Of(); var user = new UserDto { Id = 1, Name = "Bob", Email = "bob@example.com" }; - mockRepo.Setup.GetByIdAsync(1).Returns(user); + mockRepo.GetByIdAsync(1).Returns(user); // Act — orchestrate the mocks together as a service would IUserRepository repo = mockRepo.Object; INotificationService notify = mockNotify.Object; @@ -297,9 +297,9 @@ public async Task Multiple_Mocks_Injected_Into_Service_Orchestration() logger.Log("Info", "Welcome email sent"); // Verify all three mocks - mockRepo.Verify.GetByIdAsync(1).WasCalled(Times.Once); - mockNotify.Verify.SendEmailAsync("bob@example.com", "Welcome", "Hello Bob!").WasCalled(Times.Once); - mockLogger.Verify.Log("Info", "Welcome email sent").WasCalled(Times.Once); + mockRepo.GetByIdAsync(1).WasCalled(Times.Once); + mockNotify.SendEmailAsync("bob@example.com", "Welcome", "Hello Bob!").WasCalled(Times.Once); + mockLogger.Log("Info", "Welcome email sent").WasCalled(Times.Once); } [Test] @@ -310,9 +310,9 @@ public async Task Logger_Method_Overloads_Distinct_Setups() var twoArgCallCount = 0; var threeArgCallCount = 0; - mock.Setup.Log(Arg.Any(), Arg.Any()) + mock.Log(Arg.Any(), Arg.Any()) .Callback(() => twoArgCallCount++); - mock.Setup.Log(Arg.Any(), Arg.Any(), Arg.Any()) + mock.Log(Arg.Any(), Arg.Any(), Arg.Any()) .Callback(() => threeArgCallCount++); ILogger logger = mock.Object; @@ -326,8 +326,8 @@ public async Task Logger_Method_Overloads_Distinct_Setups() await Assert.That(threeArgCallCount).IsEqualTo(1); // Verify - mock.Verify.Log(Arg.Any(), Arg.Any()).WasCalled(Times.Once); - mock.Verify.Log(Arg.Any(), Arg.Any(), Arg.Any()).WasCalled(Times.Once); + mock.Log(Arg.Any(), Arg.Any()).WasCalled(Times.Once); + mock.Log(Arg.Any(), Arg.Any(), Arg.Any()).WasCalled(Times.Once); } [Test] @@ -338,8 +338,8 @@ public async Task Cache_Generic_Methods_With_Different_Types() var user = new UserDto { Id = 1, Name = "Alice", Email = "alice@example.com" }; var order = new OrderDto { OrderId = 42, ItemName = "Widget", Price = 9.99m }; - mock.Setup.Get("user:1").Returns(user); - mock.Setup.Get("order:42").Returns(order); + mock.Get("user:1").Returns(user); + mock.Get("order:42").Returns(order); ICache cache = mock.Object; @@ -363,8 +363,8 @@ public async Task Notification_Conditional_Send() { // Arrange — SendSmsAsync returns true for one number, false for another var mock = Mock.Of(); - mock.Setup.SendSmsAsync("+1234567890", Arg.Any()).Returns(true); - mock.Setup.SendSmsAsync("+0000000000", Arg.Any()).Returns(false); + mock.SendSmsAsync("+1234567890", Arg.Any()).Returns(true); + mock.SendSmsAsync("+0000000000", Arg.Any()).Returns(false); INotificationService notify = mock.Object; @@ -391,7 +391,7 @@ public async Task Complex_Dictionary_Return_Type() ["revenue"] = [100.50m, 200.75m, 300.00m], ["costs"] = [50.25m, 75.00m], }; - mock.Setup.GetMetricsAsync("finance").Returns(metrics); + mock.GetMetricsAsync("finance").Returns(metrics); IAnalyticsService analytics = mock.Object; @@ -411,8 +411,8 @@ public async Task Tuple_Return_Type() { // Arrange var mock = Mock.Of(); - mock.Setup.Validate("good-input").Returns((true, (string?)null)); - mock.Setup.Validate("bad-input").Returns((false, (string?)"Invalid format")); + mock.Validate("good-input").Returns((true, (string?)null)); + mock.Validate("bad-input").Returns((false, (string?)"Invalid format")); IAnalyticsService analytics = mock.Object; @@ -438,7 +438,7 @@ public async Task ReadOnlyDictionary_Return() [2] = "Inactive", [3] = "Pending", }; - mock.Setup.GetLookupAsync() + mock.GetLookupAsync() .Returns((IReadOnlyDictionary)lookup); IAnalyticsService analytics = mock.Object; @@ -467,7 +467,7 @@ public async Task DI_Integration_Happy_Path() var mockLogger = Mock.Of(); var user = new UserDto { Id = 1, Name = "Alice", Email = "alice@example.com" }; - mockRepo.Setup.GetByIdAsync(1).Returns(user); + mockRepo.GetByIdAsync(1).Returns(user); var service = new OrderService(mockRepo.Object, mockNotify.Object, mockLogger.Object); @@ -478,17 +478,17 @@ public async Task DI_Integration_Happy_Path() await Assert.That(result).IsTrue(); // Verify the repo was queried - mockRepo.Verify.GetByIdAsync(1).WasCalled(Times.Once); + mockRepo.GetByIdAsync(1).WasCalled(Times.Once); // Verify email was sent to the correct address - mockNotify.Verify.SendEmailAsync( + mockNotify.SendEmailAsync( "alice@example.com", "Order Placed", "Your order for Widget has been placed." ).WasCalled(Times.Once); // Verify info was logged - mockLogger.Verify.Log("Info", "Order placed for user 1").WasCalled(Times.Once); + mockLogger.Log("Info", "Order placed for user 1").WasCalled(Times.Once); } [Test] @@ -499,7 +499,7 @@ public async Task DI_Integration_User_Not_Found() var mockNotify = Mock.Of(); var mockLogger = Mock.Of(); - mockRepo.Setup.GetByIdAsync(999).Returns((UserDto?)null); + mockRepo.GetByIdAsync(999).Returns((UserDto?)null); var service = new OrderService(mockRepo.Object, mockNotify.Object, mockLogger.Object); @@ -510,10 +510,10 @@ public async Task DI_Integration_User_Not_Found() await Assert.That(result).IsFalse(); // Verify warning was logged - mockLogger.Verify.Log("Warning", "User 999 not found").WasCalled(Times.Once); + mockLogger.Log("Warning", "User 999 not found").WasCalled(Times.Once); // Verify email was NEVER sent - mockNotify.Verify.SendEmailAsync( + mockNotify.SendEmailAsync( Arg.Any(), Arg.Any(), Arg.Any() ).WasNeverCalled(); } @@ -529,9 +529,9 @@ public async Task DI_Integration_Verify_Exact_Email_Content() var bodyArg = Arg.Any(); var user = new UserDto { Id = 7, Name = "Charlie", Email = "charlie@example.com" }; - mockRepo.Setup.GetByIdAsync(7).Returns(user); + mockRepo.GetByIdAsync(7).Returns(user); // SendEmailAsync returns Task (void-async), so use Callback to capture args - mockNotify.Setup.SendEmailAsync( + mockNotify.SendEmailAsync( Arg.Any(), Arg.Any(), bodyArg ).Callback(() => { }); @@ -554,7 +554,7 @@ public async Task Nullable_String_Return_Configured_Null() { // Arrange var mock = Mock.Of(); - mock.Setup.GetNullableString(1).Returns((string?)null); + mock.GetNullableString(1).Returns((string?)null); INullableService svc = mock.Object; @@ -571,9 +571,9 @@ public async Task Nullable_Parameter_Matching() // Arrange var mock = Mock.Of(); var callCount = 0; - mock.Setup.Process(Arg.IsNull(), Arg.Any()) + mock.Process(Arg.IsNull(), Arg.Any()) .Callback(() => callCount++); - mock.Setup.Process(Arg.IsNotNull(), Arg.Any()) + mock.Process(Arg.IsNotNull(), Arg.Any()) .Callback(() => callCount += 10); INullableService svc = mock.Object; @@ -592,7 +592,7 @@ public async Task Nullable_Async_Return() { // Arrange var mock = Mock.Of(); - mock.Setup.FindUserAsync(Arg.Any()).Returns((UserDto?)null); + mock.FindUserAsync(Arg.Any()).Returns((UserDto?)null); INullableService svc = mock.Object; @@ -603,7 +603,7 @@ public async Task Nullable_Async_Return() await Assert.That(result).IsNull(); // Now configure to return a user for a specific name - mock.Setup.FindUserAsync("Alice") + mock.FindUserAsync("Alice") .Returns((UserDto?)new UserDto { Id = 1, Name = "Alice", Email = "alice@example.com" }); var found = await svc.FindUserAsync("Alice"); diff --git a/TUnit.Mocks.Tests/RegexMatcherTests.cs b/TUnit.Mocks.Tests/RegexMatcherTests.cs index 523a53f104..896ffcec69 100644 --- a/TUnit.Mocks.Tests/RegexMatcherTests.cs +++ b/TUnit.Mocks.Tests/RegexMatcherTests.cs @@ -13,7 +13,7 @@ public async Task Arg_Matches_With_Pattern_Matches_Matching_Strings() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Matches(@"^[A-Z]")).Returns("capitalized"); + mock.Greet(Arg.Matches(@"^[A-Z]")).Returns("capitalized"); // Act var greeter = mock.Object; @@ -28,7 +28,7 @@ public async Task Arg_Matches_With_Pattern_Does_Not_Match_NonMatching() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Matches(@"^[A-Z]")).Returns("capitalized"); + mock.Greet(Arg.Matches(@"^[A-Z]")).Returns("capitalized"); // Act var greeter = mock.Object; @@ -44,7 +44,7 @@ public async Task Arg_Matches_With_Regex_Object() // Arrange var regex = new Regex(@"\d{3}-\d{4}", RegexOptions.Compiled); var mock = Mock.Of(); - mock.Setup.Greet(Arg.Matches(regex)).Returns("phone"); + mock.Greet(Arg.Matches(regex)).Returns("phone"); // Act var greeter = mock.Object; @@ -59,7 +59,7 @@ public async Task Arg_Matches_Regex_Does_Not_Match_Null() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Matches(".*")).Returns("matched"); + mock.Greet(Arg.Matches(".*")).Returns("matched"); // Act var greeter = mock.Object; @@ -73,7 +73,7 @@ public async Task Arg_Matches_Regex_With_Email_Pattern() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Matches(@"^[\w.+-]+@[\w-]+\.[\w.]+$")).Returns("email"); + mock.Greet(Arg.Matches(@"^[\w.+-]+@[\w-]+\.[\w.]+$")).Returns("email"); // Act var greeter = mock.Object; diff --git a/TUnit.Mocks.Tests/ResetTests.cs b/TUnit.Mocks.Tests/ResetTests.cs index 33b78b2ab8..008c5f2e90 100644 --- a/TUnit.Mocks.Tests/ResetTests.cs +++ b/TUnit.Mocks.Tests/ResetTests.cs @@ -15,8 +15,8 @@ public async Task Reset_Clears_All_Setups() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(42); - mock.Setup.Add(3, 4).Returns(99); + mock.Add(1, 2).Returns(42); + mock.Add(3, 4).Returns(99); ICalculator calc = mock.Object; await Assert.That(calc.Add(1, 2)).IsEqualTo(42); @@ -41,13 +41,13 @@ public async Task Reset_Clears_Call_History() calc.Add(5, 6); // Verify calls were recorded - mock.Verify.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(3)); + mock.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(3)); // Act mock.Reset(); // Assert — after reset, call history is cleared - mock.Verify.Add(Arg.Any(), Arg.Any()).WasNeverCalled(); + mock.Add(Arg.Any(), Arg.Any()).WasNeverCalled(); await Assert.That(true).IsTrue(); } @@ -56,14 +56,14 @@ public async Task Reset_Allows_Fresh_Setup() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(42); + mock.Add(1, 2).Returns(42); ICalculator calc = mock.Object; await Assert.That(calc.Add(1, 2)).IsEqualTo(42); // Act — reset and reconfigure with different return value mock.Reset(); - mock.Setup.Add(1, 2).Returns(100); + mock.Add(1, 2).Returns(100); // Assert — new setup is in effect await Assert.That(calc.Add(1, 2)).IsEqualTo(100); @@ -78,7 +78,7 @@ public async Task Reset_Allows_Fresh_Verification() calc.Add(1, 2); calc.Add(1, 2); - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(2)); + mock.Add(1, 2).WasCalled(Times.Exactly(2)); // Act mock.Reset(); @@ -87,7 +87,7 @@ public async Task Reset_Allows_Fresh_Verification() calc.Add(1, 2); // Assert — verification reflects only post-reset calls - mock.Verify.Add(1, 2).WasCalled(Times.Once); + mock.Add(1, 2).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -96,7 +96,7 @@ public async Task Reset_On_Strict_Mock_Restores_Strict_Behavior() { // Arrange — strict mock with a configured method var mock = Mock.Of(MockBehavior.Strict); - mock.Setup.Add(1, 2).Returns(3); + mock.Add(1, 2).Returns(3); ICalculator calc = mock.Object; await Assert.That(calc.Add(1, 2)).IsEqualTo(3); @@ -119,7 +119,7 @@ public async Task Reset_Clears_String_Method_Setup() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet("Alice").Returns("Hello, Alice!"); + mock.Greet("Alice").Returns("Hello, Alice!"); IGreeter greeter = mock.Object; await Assert.That(greeter.Greet("Alice")).IsEqualTo("Hello, Alice!"); @@ -141,13 +141,13 @@ public async Task Reset_Clears_Void_Method_Call_History() calc.Log("message1"); calc.Log("message2"); - mock.Verify.Log(Arg.Any()).WasCalled(Times.Exactly(2)); + mock.Log(Arg.Any()).WasCalled(Times.Exactly(2)); // Act mock.Reset(); // Assert — void method call history is cleared - mock.Verify.Log(Arg.Any()).WasNeverCalled(); + mock.Log(Arg.Any()).WasNeverCalled(); await Assert.That(true).IsTrue(); } @@ -156,17 +156,17 @@ public async Task Reset_Followed_By_New_Setup_And_Verification() { // Arrange — full lifecycle: setup, use, reset, re-setup, re-use, re-verify var mock = Mock.Of(); - mock.Setup.Add(1, 1).Returns(10); + mock.Add(1, 1).Returns(10); ICalculator calc = mock.Object; calc.Add(1, 1); - mock.Verify.Add(1, 1).WasCalled(Times.Once); + mock.Add(1, 1).WasCalled(Times.Once); // Act — reset mock.Reset(); // Re-setup with new values - mock.Setup.Add(1, 1).Returns(20); + mock.Add(1, 1).Returns(20); // Re-use calc.Add(1, 1); @@ -174,7 +174,7 @@ public async Task Reset_Followed_By_New_Setup_And_Verification() // Assert — new setup and history await Assert.That(calc.Add(1, 1)).IsEqualTo(20); - mock.Verify.Add(1, 1).WasCalled(Times.Exactly(3)); // 2 from re-use + 1 from the assert line + mock.Add(1, 1).WasCalled(Times.Exactly(3)); // 2 from re-use + 1 from the assert line await Assert.That(true).IsTrue(); } @@ -186,17 +186,17 @@ public async Task Multiple_Resets() ICalculator calc = mock.Object; // First cycle - mock.Setup.Add(1, 1).Returns(10); + mock.Add(1, 1).Returns(10); await Assert.That(calc.Add(1, 1)).IsEqualTo(10); mock.Reset(); // Second cycle - mock.Setup.Add(1, 1).Returns(20); + mock.Add(1, 1).Returns(20); await Assert.That(calc.Add(1, 1)).IsEqualTo(20); mock.Reset(); // Third cycle - mock.Setup.Add(1, 1).Returns(30); + mock.Add(1, 1).Returns(30); await Assert.That(calc.Add(1, 1)).IsEqualTo(30); mock.Reset(); diff --git a/TUnit.Mocks.Tests/SequentialBehaviorTests.cs b/TUnit.Mocks.Tests/SequentialBehaviorTests.cs index 60881e7b21..d8206c3e2b 100644 --- a/TUnit.Mocks.Tests/SequentialBehaviorTests.cs +++ b/TUnit.Mocks.Tests/SequentialBehaviorTests.cs @@ -13,7 +13,7 @@ public async Task Throws_Then_Returns_First_Call_Throws_Second_Returns() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Throws() .Then() .Returns(5); @@ -34,7 +34,7 @@ public async Task ReturnsSequentially_Returns_Values_In_Order() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .ReturnsSequentially(1, 2, 3); ICalculator calc = mock.Object; @@ -50,7 +50,7 @@ public async Task ReturnsSequentially_Last_Value_Repeats() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .ReturnsSequentially(10, 20); ICalculator calc = mock.Object; @@ -68,7 +68,7 @@ public async Task Void_Method_Callback_Then_Throws() // Arrange var callbackInvoked = false; var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Callback(() => callbackInvoked = true) .Then() .Throws(); @@ -89,7 +89,7 @@ public async Task Returns_Then_Throws_Sequence() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 1) + mock.Add(1, 1) .Returns(42) .Then() .Throws(); @@ -109,7 +109,7 @@ public async Task Chained_Returns_With_Then() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Any()) + mock.Greet(Arg.Any()) .Returns("first") .Then() .Returns("second") diff --git a/TUnit.Mocks.Tests/SmartDefaultTests.cs b/TUnit.Mocks.Tests/SmartDefaultTests.cs index 88fb23b7c8..06ffef5b8f 100644 --- a/TUnit.Mocks.Tests/SmartDefaultTests.cs +++ b/TUnit.Mocks.Tests/SmartDefaultTests.cs @@ -126,8 +126,8 @@ public async Task Configured_Overrides_Smart_Default() { // Arrange var mock = Mock.Of(); - mock.Setup.GetName().Returns("custom"); - mock.Setup.GetCount().Returns(42); + mock.GetName().Returns("custom"); + mock.GetCount().Returns(42); // Act IDefaultsService svc = mock.Object; diff --git a/TUnit.Mocks.Tests/StateMachineTests.cs b/TUnit.Mocks.Tests/StateMachineTests.cs index 9e5e413e81..8fe1d67182 100644 --- a/TUnit.Mocks.Tests/StateMachineTests.cs +++ b/TUnit.Mocks.Tests/StateMachineTests.cs @@ -17,14 +17,14 @@ public async Task State_Machine_Returns_Different_Values_Per_State() var mock = Mock.Of(); mock.SetState("disconnected"); - mock.InState("disconnected", setup => + mock.InState("disconnected", m => { - setup.GetStatus().Returns("OFFLINE"); + m.GetStatus().Returns("OFFLINE"); }); - mock.InState("connected", setup => + mock.InState("connected", m => { - setup.GetStatus().Returns("ONLINE"); + m.GetStatus().Returns("ONLINE"); }); IConnection conn = mock.Object; @@ -44,16 +44,16 @@ public async Task TransitionsTo_Changes_State_After_Call() var mock = Mock.Of(); mock.SetState("disconnected"); - mock.InState("disconnected", setup => + mock.InState("disconnected", m => { - setup.Connect().TransitionsTo("connected"); - setup.GetStatus().Returns("OFFLINE"); + m.Connect().TransitionsTo("connected"); + m.GetStatus().Returns("OFFLINE"); }); - mock.InState("connected", setup => + mock.InState("connected", m => { - setup.Disconnect().TransitionsTo("disconnected"); - setup.GetStatus().Returns("ONLINE"); + m.Disconnect().TransitionsTo("disconnected"); + m.GetStatus().Returns("ONLINE"); }); IConnection conn = mock.Object; @@ -73,14 +73,14 @@ public async Task State_Scoped_Throws() var mock = Mock.Of(); mock.SetState("connected"); - mock.InState("connected", setup => + mock.InState("connected", m => { - setup.Connect().Throws(); + m.Connect().Throws(); }); - mock.InState("disconnected", setup => + mock.InState("disconnected", m => { - setup.Disconnect().Throws(); + m.Disconnect().Throws(); }); IConnection conn = mock.Object; @@ -100,7 +100,7 @@ public async Task No_State_Setups_Match_In_Any_State() mock.SetState("disconnected"); // Setup without state guard — matches in any state - mock.Setup.GetStatus().Returns("ALWAYS"); + mock.GetStatus().Returns("ALWAYS"); IConnection conn = mock.Object; await Assert.That(conn.GetStatus()).IsEqualTo("ALWAYS"); @@ -118,12 +118,12 @@ public async Task State_Scoped_Setup_Overrides_Global_When_In_State() var mock = Mock.Of(); // Global setup (no state guard) - mock.Setup.GetStatus().Returns("DEFAULT"); + mock.GetStatus().Returns("DEFAULT"); // State-scoped setup - mock.InState("special", setup => + mock.InState("special", m => { - setup.GetStatus().Returns("SPECIAL"); + m.GetStatus().Returns("SPECIAL"); }); IConnection conn = mock.Object; @@ -146,9 +146,9 @@ public async Task Strict_Mode_Throws_For_Unconfigured_Call_In_State() var mock = Mock.Of(MockBehavior.Strict); mock.SetState("disconnected"); - mock.InState("disconnected", setup => + mock.InState("disconnected", m => { - setup.GetStatus().Returns("OFFLINE"); + m.GetStatus().Returns("OFFLINE"); }); // No setup for Connect in "disconnected" state — strict mode should throw @@ -165,18 +165,18 @@ public async Task Nested_InState_Restores_Previous_State_Scope() var mock = Mock.Of(); mock.SetState("outer"); - mock.InState("outer", outerSetup => + mock.InState("outer", m => { - outerSetup.GetStatus().Returns("OUTER"); + m.GetStatus().Returns("OUTER"); // Nested InState should temporarily switch to "inner" scope - mock.InState("inner", innerSetup => + mock.InState("inner", m => { - innerSetup.Connect(); + m.Connect(); }); // After inner InState returns, we should be back in "outer" scope - outerSetup.Disconnect(); + m.Disconnect(); }); IConnection conn = mock.Object; @@ -196,12 +196,12 @@ public async Task SetState_Null_Clears_State() var mock = Mock.Of(); // Global (no-state) setup — added first - mock.Setup.GetStatus().Returns("NO_STATE"); + mock.GetStatus().Returns("NO_STATE"); // State-scoped setup — added second, wins when in "connected" state - mock.InState("connected", setup => + mock.InState("connected", m => { - setup.GetStatus().Returns("ONLINE"); + m.GetStatus().Returns("ONLINE"); }); mock.SetState("connected"); @@ -232,15 +232,15 @@ public async Task Verify_Works_With_State_Scoped_Setups() var mock = Mock.Of(); mock.SetState("disconnected"); - mock.InState("disconnected", setup => + mock.InState("disconnected", m => { - setup.Connect().TransitionsTo("connected"); + m.Connect().TransitionsTo("connected"); }); IConnection conn = mock.Object; conn.Connect(); // Verification should still work — the call was recorded - mock.Verify!.Connect().WasCalled(Times.Once); + mock.Connect().WasCalled(Times.Once); } } diff --git a/TUnit.Mocks.Tests/StrictModeTests.cs b/TUnit.Mocks.Tests/StrictModeTests.cs index f5cf3a22bb..336674622a 100644 --- a/TUnit.Mocks.Tests/StrictModeTests.cs +++ b/TUnit.Mocks.Tests/StrictModeTests.cs @@ -45,7 +45,7 @@ public async Task Strict_Configured_Method_Works_Normally() { // Arrange var mock = Mock.Of(MockBehavior.Strict); - mock.Setup.Add(2, 3).Returns(5); + mock.Add(2, 3).Returns(5); // Act ICalculator calc = mock.Object; @@ -60,7 +60,7 @@ public async Task Strict_Configured_Void_Method_Does_Not_Throw() { // Arrange var mock = Mock.Of(MockBehavior.Strict); - mock.Setup.Log("expected message"); + mock.Log("expected message"); // Act & Assert — configured void method should not throw ICalculator calc = mock.Object; @@ -123,7 +123,7 @@ public async Task Strict_Mixed_Some_Configured_Some_Not() { // Arrange — configure Add but not Log or GetName var mock = Mock.Of(MockBehavior.Strict); - mock.Setup.Add(1, 2).Returns(3); + mock.Add(1, 2).Returns(3); ICalculator calc = mock.Object; @@ -151,7 +151,7 @@ public async Task Strict_Configured_Args_Mismatch_Throws() { // Arrange — configure Add with specific args var mock = Mock.Of(MockBehavior.Strict); - mock.Setup.Add(1, 2).Returns(3); + mock.Add(1, 2).Returns(3); ICalculator calc = mock.Object; diff --git a/TUnit.Mocks.Tests/ThreadSafetyTests.cs b/TUnit.Mocks.Tests/ThreadSafetyTests.cs index 0ede46dea3..9607b4f629 100644 --- a/TUnit.Mocks.Tests/ThreadSafetyTests.cs +++ b/TUnit.Mocks.Tests/ThreadSafetyTests.cs @@ -13,7 +13,7 @@ public async Task Concurrent_Calls_Are_Thread_Safe() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; // Act — 100 concurrent calls @@ -40,7 +40,7 @@ public async Task Concurrent_Void_Calls_Are_Thread_Safe() await Task.WhenAll(tasks); // Assert — all 100 calls should be recorded - mock.Verify.Log(Arg.Any()).WasCalled(Times.Exactly(100)); + mock.Log(Arg.Any()).WasCalled(Times.Exactly(100)); await Assert.That(true).IsTrue(); } @@ -56,7 +56,7 @@ public async Task Concurrent_Setup_And_Call() { for (int i = 0; i < 50; i++) { - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(i); + mock.Add(Arg.Any(), Arg.Any()).Returns(i); } }); @@ -79,9 +79,9 @@ public async Task Concurrent_Calls_With_Different_Args() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 1).Returns(10); - mock.Setup.Add(2, 2).Returns(20); - mock.Setup.Add(3, 3).Returns(30); + mock.Add(1, 1).Returns(10); + mock.Add(2, 2).Returns(20); + mock.Add(3, 3).Returns(30); ICalculator calc = mock.Object; // Act — concurrent calls with different args @@ -116,7 +116,7 @@ public async Task Concurrent_Verification_Is_Thread_Safe() // Now verify concurrently from multiple threads var verifyTasks = Enumerable.Range(0, 20).Select(_ => Task.Run(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(10)); + mock.Add(1, 2).WasCalled(Times.Exactly(10)); })); await Task.WhenAll(verifyTasks); @@ -130,11 +130,11 @@ public async Task Concurrent_Calls_On_Different_Interfaces() { // Arrange var calcMock = Mock.Of(); - calcMock.Setup.Add(Arg.Any(), Arg.Any()).Returns(99); + calcMock.Add(Arg.Any(), Arg.Any()).Returns(99); ICalculator calc = calcMock.Object; var greeterMock = Mock.Of(); - greeterMock.Setup.Greet(Arg.Any()).Returns("hi"); + greeterMock.Greet(Arg.Any()).Returns("hi"); IGreeter greeter = greeterMock.Object; // Act — concurrent calls on both mocks @@ -164,7 +164,7 @@ public async Task Concurrent_Calls_All_Recorded_In_History() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Any()).Returns("hello"); + mock.Greet(Arg.Any()).Returns("hello"); IGreeter greeter = mock.Object; // Act — 100 concurrent calls @@ -173,7 +173,7 @@ public async Task Concurrent_Calls_All_Recorded_In_History() await Task.WhenAll(tasks); // Assert — verify total call count - mock.Verify.Greet(Arg.Any()).WasCalled(Times.Exactly(100)); + mock.Greet(Arg.Any()).WasCalled(Times.Exactly(100)); await Assert.That(true).IsTrue(); } } diff --git a/TUnit.Mocks.Tests/TypedCallbackTests.cs b/TUnit.Mocks.Tests/TypedCallbackTests.cs index 80d8537f44..467fd6ee86 100644 --- a/TUnit.Mocks.Tests/TypedCallbackTests.cs +++ b/TUnit.Mocks.Tests/TypedCallbackTests.cs @@ -14,7 +14,7 @@ public async Task Callback_With_Args_Receives_Arguments() // Arrange object?[]? capturedArgs = null; var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Callback((Action)(args => capturedArgs = args)); ICalculator calc = mock.Object; @@ -35,7 +35,7 @@ public async Task Callback_With_Args_On_Void_Method() // Arrange object?[]? capturedArgs = null; var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Callback((Action)(args => capturedArgs = args)); ICalculator calc = mock.Object; @@ -54,7 +54,7 @@ public async Task Returns_With_Args_Computes_From_Arguments() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Returns((Func)(args => (int)args[0]! + (int)args[1]!)); ICalculator calc = mock.Object; @@ -70,7 +70,7 @@ public async Task Returns_With_Args_String_Concatenation() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet(Arg.Any()) + mock.Greet(Arg.Any()) .Returns((Func)(args => $"Hello, {args[0]}!")); IGreeter greeter = mock.Object; @@ -85,7 +85,7 @@ public async Task Computed_Throw_With_Args() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Throws((Func)(args => new ArgumentException($"Bad args: {args[0]}, {args[1]}"))); @@ -101,7 +101,7 @@ public async Task Computed_Throw_On_Void_Method() { // Arrange var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Throws((Func)(args => new InvalidOperationException($"Cannot log: {args[0]}"))); @@ -118,7 +118,7 @@ public async Task Callback_With_Args_Then_Returns() // Arrange object?[]? capturedArgs = null; var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Callback((Action)(args => capturedArgs = args)) .Then() .Returns(42); @@ -140,7 +140,7 @@ public async Task Returns_With_Args_Repeats_On_Subsequent_Calls() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Returns((Func)(args => (int)args[0]! * (int)args[1]!)); ICalculator calc = mock.Object; @@ -157,7 +157,7 @@ public async Task Returns_With_Args_Repeats_On_Subsequent_Calls() public async Task StronglyTyped_Returns_Computes_From_Arguments() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns((int a, int b) => a + b); + mock.Add(Arg.Any(), Arg.Any()).Returns((int a, int b) => a + b); ICalculator calc = mock.Object; @@ -172,7 +172,7 @@ public async Task StronglyTyped_Callback_Receives_Arguments() var capturedArgs = new List<(int a, int b)>(); // Callback is a behavior — first call runs callback, second call runs Returns - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Callback((int a, int b) => capturedArgs.Add((a, b))); ICalculator calc = mock.Object; @@ -189,7 +189,7 @@ public async Task StronglyTyped_Callback_Receives_Arguments() public async Task StronglyTyped_Throws_With_Argument_Dependent_Exception() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Throws((int a, int b) => new ArgumentException($"Cannot add {a} and {b}")); ICalculator calc = mock.Object; @@ -204,7 +204,7 @@ public async Task StronglyTyped_Void_Callback() var mock = Mock.Of(); string? capturedMessage = null; - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Callback((string msg) => capturedMessage = msg); ICalculator calc = mock.Object; @@ -217,7 +217,7 @@ public async Task StronglyTyped_Void_Callback() public async Task StronglyTyped_Void_Throws() { var mock = Mock.Of(); - mock.Setup.Log(Arg.Any()) + mock.Log(Arg.Any()) .Throws((string msg) => new InvalidOperationException($"Cannot log: {msg}")); ICalculator calc = mock.Object; @@ -230,7 +230,7 @@ public async Task StronglyTyped_Void_Throws() public async Task StronglyTyped_Returns_Single_Parameter() { var mock = Mock.Of(); - mock.Setup.Greet(Arg.Any()).Returns((string name) => $"Hello, {name}!"); + mock.Greet(Arg.Any()).Returns((string name) => $"Hello, {name}!"); IGreeter greeter = mock.Object; @@ -241,7 +241,7 @@ public async Task StronglyTyped_Returns_Single_Parameter() public async Task StronglyTyped_With_Then_Chain() { var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Returns((int a, int b) => a + b) .Then() .Returns(99); @@ -257,7 +257,7 @@ public async Task StronglyTyped_Existing_Untyped_Returns_Still_Works() { // Verify that existing untyped API still compiles and works var mock = Mock.Of(); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); ICalculator calc = mock.Object; @@ -269,7 +269,7 @@ public async Task StronglyTyped_Existing_Untyped_Callback_Still_Works() { var mock = Mock.Of(); var called = false; - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Callback(() => called = true) .Then() .Returns(0); diff --git a/TUnit.Mocks.Tests/VerificationMessageTests.cs b/TUnit.Mocks.Tests/VerificationMessageTests.cs index dc566870a9..5c69116a26 100644 --- a/TUnit.Mocks.Tests/VerificationMessageTests.cs +++ b/TUnit.Mocks.Tests/VerificationMessageTests.cs @@ -22,7 +22,7 @@ public async Task WasCalled_With_Custom_Message_Includes_It() // Assert — verify expects exactly twice with custom message var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(2), "Expected retry logic to call twice"); + mock.Add(1, 2).WasCalled(Times.Exactly(2), "Expected retry logic to call twice"); }); await Assert.That(ex.Message).Contains("Expected retry logic to call twice"); @@ -40,7 +40,7 @@ public async Task WasNeverCalled_With_Custom_Message_Includes_It() // Assert var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasNeverCalled("Should not have called Add in read-only mode"); + mock.Add(1, 2).WasNeverCalled("Should not have called Add in read-only mode"); }); await Assert.That(ex.Message).Contains("Should not have called Add in read-only mode"); @@ -56,7 +56,7 @@ public async Task WasCalled_Shorthand_With_Custom_Message_Includes_It() // Assert — not called at all var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled("Expected at least one Add call"); + mock.Add(1, 2).WasCalled("Expected at least one Add call"); }); await Assert.That(ex.Message).Contains("Expected at least one Add call"); @@ -72,7 +72,7 @@ public async Task WasCalled_Without_Message_Has_Standard_Output() // Assert var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Once); + mock.Add(1, 2).WasCalled(Times.Once); }); // Should NOT have a custom message line before "Mock verification failed." @@ -88,7 +88,7 @@ public async Task WasCalled_With_Null_Message_Has_Standard_Output() // Assert var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Once, null); + mock.Add(1, 2).WasCalled(Times.Once, null); }); await Assert.That(ex.Message).StartsWith("Mock verification failed."); @@ -103,7 +103,7 @@ public async Task WasCalled_With_Empty_Message_Has_Standard_Output() // Assert var ex = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Once, ""); + mock.Add(1, 2).WasCalled(Times.Once, ""); }); await Assert.That(ex.Message).StartsWith("Mock verification failed."); diff --git a/TUnit.Mocks.Tests/VerificationTests.cs b/TUnit.Mocks.Tests/VerificationTests.cs index c6d1b1400c..8863bd2747 100644 --- a/TUnit.Mocks.Tests/VerificationTests.cs +++ b/TUnit.Mocks.Tests/VerificationTests.cs @@ -14,14 +14,14 @@ public async Task Verify_Once_Succeeds_When_Called_Once() { // Arrange var mock = Mock.Of(); - mock.Setup.Add(1, 2).Returns(3); + mock.Add(1, 2).Returns(3); // Act ICalculator calc = mock.Object; calc.Add(1, 2); // Assert - mock.Verify.Add(1, 2).WasCalled(Times.Once); + mock.Add(1, 2).WasCalled(Times.Once); await Assert.That(true).IsTrue(); // test completes without exception } @@ -38,7 +38,7 @@ public async Task Verify_Fails_With_Descriptive_Message_When_Count_Wrong() // Assert — verify expects exactly twice, should fail var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(2)); + mock.Add(1, 2).WasCalled(Times.Exactly(2)); }); await Assert.That(exception.Message).Contains("Mock verification failed"); @@ -55,7 +55,7 @@ public async Task Verify_Never_Succeeds_When_Not_Called() // Act — don't call anything // Assert - mock.Verify.Add(1, 2).WasNeverCalled(); + mock.Add(1, 2).WasNeverCalled(); await Assert.That(true).IsTrue(); } @@ -72,7 +72,7 @@ public async Task Verify_Never_Fails_When_Called() // Assert var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasNeverCalled(); + mock.Add(1, 2).WasNeverCalled(); }); await Assert.That(exception.ActualCount).IsEqualTo(1); @@ -91,7 +91,7 @@ public async Task Verify_AtLeast_Succeeds() calc.Add(1, 2); // Assert — at least 2 should pass - mock.Verify.Add(1, 2).WasCalled(Times.AtLeast(2)); + mock.Add(1, 2).WasCalled(Times.AtLeast(2)); await Assert.That(true).IsTrue(); } @@ -107,7 +107,7 @@ public async Task Verify_AtMost_Succeeds() calc.Add(1, 2); // Assert — at most 3 should pass - mock.Verify.Add(1, 2).WasCalled(Times.AtMost(3)); + mock.Add(1, 2).WasCalled(Times.AtMost(3)); await Assert.That(true).IsTrue(); } @@ -126,7 +126,7 @@ public async Task Verify_AtMost_Fails_When_Exceeded() // Assert — at most 2 should fail var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.AtMost(2)); + mock.Add(1, 2).WasCalled(Times.AtMost(2)); }); await Assert.That(exception.ActualCount).IsEqualTo(3); @@ -144,7 +144,7 @@ public async Task Verify_Between_Succeeds() calc.Add(1, 2); // Assert — between 1 and 3 should pass - mock.Verify.Add(1, 2).WasCalled(Times.Between(1, 3)); + mock.Add(1, 2).WasCalled(Times.Between(1, 3)); await Assert.That(true).IsTrue(); } @@ -161,7 +161,7 @@ public async Task Verify_Between_Fails_When_Outside_Range() // Assert — between 2 and 4 should fail (only 1 call) var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(Times.Between(2, 4)); + mock.Add(1, 2).WasCalled(Times.Between(2, 4)); }); await Assert.That(exception.ActualCount).IsEqualTo(1); @@ -180,8 +180,8 @@ public async Task Verify_With_Exact_Args_Only_Matching_Calls_Count() calc.Add(1, 2); // Assert — only calls with (1, 2) should count - mock.Verify.Add(1, 2).WasCalled(Times.Exactly(2)); - mock.Verify.Add(3, 4).WasCalled(Times.Once); + mock.Add(1, 2).WasCalled(Times.Exactly(2)); + mock.Add(3, 4).WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -196,7 +196,7 @@ public async Task Verify_WasCalled_Shorthand_At_Least_Once() calc.Add(1, 2); // Assert — WasCalled() means at least once - mock.Verify.Add(1, 2).WasCalled(); + mock.Add(1, 2).WasCalled(); await Assert.That(true).IsTrue(); } @@ -209,7 +209,7 @@ public async Task Verify_WasCalled_Shorthand_Fails_When_Not_Called() // Assert — WasCalled() should fail when not called var exception = Assert.Throws(() => { - mock.Verify.Add(1, 2).WasCalled(); + mock.Add(1, 2).WasCalled(); }); await Assert.That(exception.ActualCount).IsEqualTo(0); @@ -227,8 +227,8 @@ public async Task Verify_Void_Method() calc.Log("world"); // Assert - mock.Verify.Log("hello").WasCalled(Times.Once); - mock.Verify.Log("world").WasCalled(Times.Once); + mock.Log("hello").WasCalled(Times.Once); + mock.Log("world").WasCalled(Times.Once); await Assert.That(true).IsTrue(); } @@ -237,7 +237,7 @@ public async Task Verify_String_Method_On_Different_Interface() { // Arrange var mock = Mock.Of(); - mock.Setup.Greet("Alice").Returns("Hello, Alice!"); + mock.Greet("Alice").Returns("Hello, Alice!"); // Act IGreeter greeter = mock.Object; @@ -245,8 +245,8 @@ public async Task Verify_String_Method_On_Different_Interface() greeter.Greet("Bob"); // Assert - mock.Verify.Greet("Alice").WasCalled(Times.Once); - mock.Verify.Greet("Bob").WasCalled(Times.Once); + mock.Greet("Alice").WasCalled(Times.Once); + mock.Greet("Bob").WasCalled(Times.Once); await Assert.That(true).IsTrue(); } } diff --git a/TUnit.Mocks.Tests/VerifyAllTests.cs b/TUnit.Mocks.Tests/VerifyAllTests.cs index d2c8e8b19c..791f72dba3 100644 --- a/TUnit.Mocks.Tests/VerifyAllTests.cs +++ b/TUnit.Mocks.Tests/VerifyAllTests.cs @@ -14,8 +14,8 @@ public interface IService public async Task VerifyAll_Passes_When_All_Setups_Invoked() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); - mock.Setup.Process(Arg.Any()); + mock.GetValue(Arg.Any()).Returns("value"); + mock.Process(Arg.Any()); var svc = mock.Object; svc.GetValue("key"); @@ -29,8 +29,8 @@ public async Task VerifyAll_Passes_When_All_Setups_Invoked() public async Task VerifyAll_Fails_When_Setup_Not_Invoked() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); - mock.Setup.Process(Arg.Any()); + mock.GetValue(Arg.Any()).Returns("value"); + mock.Process(Arg.Any()); var svc = mock.Object; svc.GetValue("key"); // Only call GetValue, not Process @@ -43,7 +43,7 @@ public async Task VerifyAll_Fails_When_Setup_Not_Invoked() public async Task VerifyAll_Fails_When_No_Setups_Called() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var ex = Assert.Throws(() => mock.VerifyAll()); await Assert.That(ex.Message).Contains("GetValue"); @@ -61,8 +61,8 @@ public async Task VerifyAll_Passes_When_No_Setups_Registered() public async Task VerifyAll_Multiple_Uninvoked_Shows_All() { var mock = Mock.Of(); - mock.Setup.GetValue("a").Returns("val"); - mock.Setup.Process(42); + mock.GetValue("a").Returns("val"); + mock.Process(42); // Don't call anything var ex = Assert.Throws(() => mock.VerifyAll()); diff --git a/TUnit.Mocks.Tests/VerifyNoOtherCallsTests.cs b/TUnit.Mocks.Tests/VerifyNoOtherCallsTests.cs index 7bfbcfde57..e061933606 100644 --- a/TUnit.Mocks.Tests/VerifyNoOtherCallsTests.cs +++ b/TUnit.Mocks.Tests/VerifyNoOtherCallsTests.cs @@ -15,12 +15,12 @@ public interface IService public async Task VerifyNoOtherCalls_Passes_When_All_Calls_Verified() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("key1"); - mock.Verify!.GetValue("key1").WasCalled(Times.Once); + mock.GetValue("key1").WasCalled(Times.Once); mock.VerifyNoOtherCalls(); await Assert.That(true).IsTrue(); @@ -30,14 +30,14 @@ public async Task VerifyNoOtherCalls_Passes_When_All_Calls_Verified() public async Task VerifyNoOtherCalls_Fails_When_Unverified_Calls_Exist() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("key1"); svc.Process(42); // Only verify GetValue, not Process - mock.Verify!.GetValue("key1").WasCalled(Times.Once); + mock.GetValue("key1").WasCalled(Times.Once); var ex = Assert.Throws(() => mock.VerifyNoOtherCalls()); await Assert.That(ex.Message).Contains("Process(42)"); @@ -55,7 +55,7 @@ public async Task VerifyNoOtherCalls_Passes_When_No_Calls_Made() public async Task VerifyNoOtherCalls_Works_After_Reset() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("key1"); @@ -70,7 +70,7 @@ public async Task VerifyNoOtherCalls_Works_After_Reset() public async Task VerifyNoOtherCalls_Multiple_Unverified_Shows_All() { var mock = Mock.Of(); - mock.Setup.GetValue(Arg.Any()).Returns("value"); + mock.GetValue(Arg.Any()).Returns("value"); var svc = mock.Object; svc.GetValue("a"); diff --git a/TUnit.Mocks.Tests/WrapRealObjectTests.cs b/TUnit.Mocks.Tests/WrapRealObjectTests.cs index f9df2f4adf..324c5886bc 100644 --- a/TUnit.Mocks.Tests/WrapRealObjectTests.cs +++ b/TUnit.Mocks.Tests/WrapRealObjectTests.cs @@ -64,7 +64,7 @@ public async Task Configured_Call_Returns_Mock_Value_Instead_Of_Real() // Arrange var real = new RealCalculator(10); var mock = Mock.Wrap(real); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(99); + mock.Add(Arg.Any(), Arg.Any()).Returns(99); // Act var result = mock.Object.Add(3, 4); @@ -79,7 +79,7 @@ public async Task Multiple_Methods_Mixed_Setup() // Arrange var real = new RealCalculator(5); var mock = Mock.Wrap(real); - mock.Setup.Add(1, 2).Returns(100); + mock.Add(1, 2).Returns(100); // Don't setup Multiply — let it go to wrapped instance // Act @@ -111,7 +111,7 @@ public async Task String_Method_Can_Be_Overridden() // Arrange var real = new RealCalculator(42); var mock = Mock.Wrap(real); - mock.Setup.Describe(Arg.Any()).Returns("mocked description"); + mock.Describe(Arg.Any()).Returns("mocked description"); // Act var result = mock.Object.Describe("test"); @@ -131,7 +131,7 @@ public void Void_Method_Delegates_To_Real_Instance() mock.Object.Log("test message"); // Assert — call was recorded for verification - mock.Verify.Log(Arg.Any()).WasCalled(Times.Once); + mock.Log(Arg.Any()).WasCalled(Times.Once); } [Test] @@ -147,8 +147,8 @@ public void Verify_Records_Calls_Even_When_Delegating() mock.Object.Multiply(5, 6); // Assert — calls are still tracked - mock.Verify.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(2)); - mock.Verify.Multiply(Arg.Any(), Arg.Any()).WasCalled(Times.Once); + mock.Add(Arg.Any(), Arg.Any()).WasCalled(Times.Exactly(2)); + mock.Multiply(Arg.Any(), Arg.Any()).WasCalled(Times.Once); } [Test] @@ -182,7 +182,7 @@ public async Task Wrap_Strict_Mode_Allows_Configured_Calls() // Arrange — strict mode with explicit setup var real = new RealCalculator(10); var mock = Mock.Wrap(MockBehavior.Strict, real); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(42); + mock.Add(Arg.Any(), Arg.Any()).Returns(42); // Act var result = mock.Object.Add(2, 3); @@ -197,7 +197,7 @@ public async Task Wrap_Returns_Configured_Value() // Arrange var real = new RealCalculator(100); var mock = Mock.Wrap(real); - mock.Setup.Add(Arg.Any(), Arg.Any()).Returns(0); + mock.Add(Arg.Any(), Arg.Any()).Returns(0); // Act var result = mock.Object.Add(5, 7); @@ -212,7 +212,7 @@ public void Wrap_Throws_Works() // Arrange var real = new RealCalculator(); var mock = Mock.Wrap(real); - mock.Setup.Add(Arg.Any(), Arg.Any()) + mock.Add(Arg.Any(), Arg.Any()) .Throws(new InvalidOperationException("mock error")); // Act & Assert diff --git a/TUnit.Mocks/IMockSetup.cs b/TUnit.Mocks/IMockSetup.cs deleted file mode 100644 index b8101f414b..0000000000 --- a/TUnit.Mocks/IMockSetup.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace TUnit.Mocks; - -/// -/// Marker interface for generated mock setup surfaces. -/// Extension methods on this interface provide strongly-typed setup members. -/// -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -public interface IMockSetup where T : class { } - -/// -/// Marker interface for generated mock verify surfaces. -/// Extension methods on this interface provide strongly-typed verify members. -/// -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -public interface IMockVerify where T : class { } - -/// -/// Marker interface for generated mock raise surfaces. -/// Extension methods on this interface provide strongly-typed raise members. -/// -[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] -public interface IMockRaise where T : class { } diff --git a/TUnit.Mocks/MockMethodCall.cs b/TUnit.Mocks/MockMethodCall.cs new file mode 100644 index 0000000000..f624192f7f --- /dev/null +++ b/TUnit.Mocks/MockMethodCall.cs @@ -0,0 +1,158 @@ +using System.ComponentModel; +using TUnit.Mocks.Arguments; +using TUnit.Mocks.Setup; +using TUnit.Mocks.Verification; + +namespace TUnit.Mocks; + +/// +/// Unified return type for non-void mock method calls. Supports both setup and verification. +/// Lazily registers the method setup only when a setup method (e.g. .Returns()) is called. +/// Unlike , non-void calls are NOT eagerly registered because +/// a non-void method without a configured return value is rarely useful. To explicitly allow +/// a non-void call in strict mode without configuring a return value, chain .Returns(default!). +/// Public for generated code access. Not intended for direct use. +/// +[EditorBrowsable(EditorBrowsableState.Never)] +public sealed class MockMethodCall : IMethodSetup, ISetupChain, ICallVerification +{ + private readonly IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly IArgumentMatcher[] _matchers; + private readonly Lazy> _lazyBuilder; + + [EditorBrowsable(EditorBrowsableState.Never)] + public MockMethodCall(IMockEngineAccess engine, int memberId, string memberName, IArgumentMatcher[] matchers) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new Lazy>(() => + { + var setup = new MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new MethodSetupBuilder(setup); + }); + } + + private MethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; + + // IMethodSetup implementation + + public ISetupChain Returns(TReturn value) + { + EnsureSetup().Returns(value); + return this; + } + + public ISetupChain Returns(Func factory) + { + EnsureSetup().Returns(factory); + return this; + } + + public ISetupChain ReturnsSequentially(params TReturn[] values) + { + EnsureSetup().ReturnsSequentially(values); + return this; + } + + public ISetupChain Throws() where TException : Exception, new() + { + EnsureSetup().Throws(); + return this; + } + + public ISetupChain Throws(Exception exception) + { + EnsureSetup().Throws(exception); + return this; + } + + public ISetupChain Callback(Action callback) + { + EnsureSetup().Callback(callback); + return this; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public ISetupChain Callback(Action callback) + { + EnsureSetup().Callback(callback); + return this; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public ISetupChain Returns(Func factory) + { + EnsureSetup().Returns(factory); + return this; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public ISetupChain Throws(Func exceptionFactory) + { + EnsureSetup().Throws(exceptionFactory); + return this; + } + + public ISetupChain Raises(string eventName, object? args = null) + { + EnsureSetup().Raises(eventName, args); + return this; + } + + public ISetupChain SetsOutParameter(int paramIndex, object? value) + { + EnsureSetup().SetsOutParameter(paramIndex, value); + return this; + } + + public ISetupChain TransitionsTo(string stateName) + { + EnsureSetup().TransitionsTo(stateName); + return this; + } + + // ISetupChain implementation + + public IMethodSetup Then() + { + EnsureSetup().Then(); + return this; + } + + // ICallVerification implementation + + public void WasCalled(Times times) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + } + + public void WasCalled(Times times, string? message) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + } + + public void WasNeverCalled() + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + } + + public void WasNeverCalled(string? message) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); + } + + public void WasCalled() + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + } + + public void WasCalled(string? message) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + } +} diff --git a/TUnit.Mocks/MockOfT.cs b/TUnit.Mocks/MockOfT.cs index 5bc8783360..e4ef159ffd 100644 --- a/TUnit.Mocks/MockOfT.cs +++ b/TUnit.Mocks/MockOfT.cs @@ -1,20 +1,17 @@ +using System.ComponentModel; using TUnit.Mocks.Exceptions; using TUnit.Mocks.Verification; namespace TUnit.Mocks; /// -/// Wraps a generated mock implementation and provides access to Setup, Verify, and Raise surfaces. -/// -/// The source generator produces extension methods on IMockSetup<T>, IMockVerify<T>, -/// and IMockRaise<T> that provide strongly-typed setup/verify/raise members. -/// This approach is fully AOT-compatible — no dynamic dispatch is needed. -/// +/// Wraps a generated mock implementation. Source-generated extension methods on Mock<T> +/// provide strongly-typed setup and verification members directly. /// public class Mock : IMock where T : class { /// The mock engine. Used by generated code. Not intended for direct use. - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] + [EditorBrowsable(EditorBrowsableState.Never)] public MockEngine Engine { get; } /// The mock object that implements T. @@ -36,40 +33,12 @@ public IDefaultValueProvider? DefaultValueProvider set => Engine.DefaultValueProvider = value; } - /// - /// Generated setup surface -- extension methods provide T's members with Arg{T} parameters. - /// - public IMockSetup Setup { get; } - - /// - /// Generated verification surface -- extension methods provide T's members with Arg{T} parameters. - /// - public IMockVerify Verify { get; internal set; } - - /// - /// Generated event-raising surface (if T has events). - /// - public IMockRaise? Raise { get; internal set; } - - /// Creates a Mock with an existing engine, setup, and verify surfaces. Used by generated code. - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public Mock(T mockObject, IMockSetup setup, IMockVerify verify, MockEngine engine) - { - Engine = engine; - Object = mockObject; - Setup = setup; - Verify = verify; - } - - /// Creates a Mock with an existing engine, setup, verify, and raise surfaces. Used by generated code. - [System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)] - public Mock(T mockObject, IMockSetup setup, IMockVerify verify, IMockRaise? raise, MockEngine engine) + /// Creates a Mock wrapping the given object and engine. Used by generated code. + [EditorBrowsable(EditorBrowsableState.Never)] + public Mock(T mockObject, MockEngine engine) { Engine = engine; Object = mockObject; - Setup = setup; - Verify = verify; - Raise = raise; } /// All calls made to this mock, in order. @@ -161,13 +130,13 @@ public Mock GetAutoMock(string memberName) where TChild : class /// Configures setups scoped to a specific state. All setups registered inside /// the action will only match when the engine is in the specified state. /// - public void InState(string stateName, Action> configure) + public void InState(string stateName, Action> configure) { var previous = Engine.PendingRequiredState; Engine.PendingRequiredState = stateName; try { - configure(Setup); + configure(this); } finally { diff --git a/TUnit.Mocks/PropertyMockCall.cs b/TUnit.Mocks/PropertyMockCall.cs new file mode 100644 index 0000000000..b4f5f8cec9 --- /dev/null +++ b/TUnit.Mocks/PropertyMockCall.cs @@ -0,0 +1,259 @@ +using System.ComponentModel; +using TUnit.Mocks.Arguments; +using TUnit.Mocks.Setup; +using TUnit.Mocks.Verification; + +namespace TUnit.Mocks; + +/// +/// Unified return type for property mock members. Supports both setup and verification. +/// Provides setup (via .Returns(), .Getter, .Setter, .Set()) +/// and verification (via .WasCalled(), .WasNeverCalled()) on a single type. +/// +/// Verification scope: The WasCalled/WasNeverCalled methods on this type +/// verify the getter only. To verify setter calls, use .Setter.WasCalled() +/// or .Set(value).WasCalled(). +/// +/// Public for generated code access. Not intended for direct use. +/// +/// The property type. +[EditorBrowsable(EditorBrowsableState.Never)] +public readonly struct PropertyMockCall : ICallVerification +{ + private readonly IMockEngineAccess _engine; + private readonly int _getterMemberId; + private readonly int _setterMemberId; + private readonly string _propertyName; + private readonly bool _hasGetter; + private readonly bool _hasSetter; + + /// Creates a new property mock call. + [EditorBrowsable(EditorBrowsableState.Never)] + public PropertyMockCall(IMockEngineAccess engine, int getterMemberId, int setterMemberId, + string propertyName, bool hasGetter, bool hasSetter) + { + _engine = engine; + _getterMemberId = getterMemberId; + _setterMemberId = setterMemberId; + _propertyName = propertyName; + _hasGetter = hasGetter; + _hasSetter = hasSetter; + } + + // --- Setup surface --- + + /// + /// Accesses the getter setup explicitly. Creates and registers a getter . + /// Note: Each access creates a new registration. This is intentional — + /// it allows chaining different behaviors (e.g. .Getter.Returns("x") then later + /// .Getter.Returns("y")) which adds a second setup that takes priority. + /// + public IPropertySetup Getter + { + get + { + if (!_hasGetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a getter."); + } + + var matchers = Array.Empty(); + var methodSetup = new MethodSetup(_getterMemberId, matchers, $"get_{_propertyName}"); + _engine.AddSetup(methodSetup); + return new PropertySetupBuilder(methodSetup); + } + } + + /// + /// Accesses the setter with any-value semantics. + /// Returns a unified type supporting both setup (.Callback(), .Throws()) + /// and verification (.WasCalled(), .WasNeverCalled()). + /// Uses deferred registration to avoid unwanted setup side-effects when accessed purely + /// for verification. Chain a setup method (.Callback(), .Throws()) to register. + /// + public VoidMockMethodCall Setter + { + get + { + if (!_hasSetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a setter."); + } + + return new VoidMockMethodCall(_engine, _setterMemberId, $"set_{_propertyName}", + Array.Empty(), eagerRegister: false); + } + } + + /// + /// Accesses the setter with a specific value matcher. + /// Returns a unified setter type supporting both setup and verification. + /// + public PropertySetterMockCall Set(Arg value) + { + if (!_hasSetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a setter."); + } + + return new PropertySetterMockCall(_engine, _setterMemberId, _propertyName, value.Matcher); + } + + // Convenience shortcuts that delegate to Getter + + /// Configure a fixed return value for the property getter. + public ISetupChain Returns(TProperty value) => Getter.Returns(value); + + /// Configure a computed return value for the property getter. + public ISetupChain Returns(Func factory) => Getter.Returns(factory); + + /// Configure sequential return values for the property getter. + public ISetupChain ReturnsSequentially(params TProperty[] values) => Getter.ReturnsSequentially(values); + + /// Configure the property getter to throw. + public ISetupChain Throws() where TException : Exception, new() => Getter.Throws(); + + /// Configure the property getter to throw a specific exception. + public ISetupChain Throws(Exception exception) => Getter.Throws(exception); + + /// Execute a callback when the property getter is called. + public ISetupChain Callback(Action callback) => Getter.Callback(callback); + + // --- Verify surface (delegates to getter verification) --- + + /// + public void WasCalled(Times times) + { + if (!_hasGetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a getter."); + } + + _engine.CreateVerification(_getterMemberId, $"get_{_propertyName}", + Array.Empty()).WasCalled(times); + } + + /// + public void WasCalled(Times times, string? message) + { + if (!_hasGetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a getter."); + } + + _engine.CreateVerification(_getterMemberId, $"get_{_propertyName}", + Array.Empty()).WasCalled(times, message); + } + + /// + public void WasNeverCalled() + { + if (!_hasGetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a getter."); + } + + _engine.CreateVerification(_getterMemberId, $"get_{_propertyName}", + Array.Empty()).WasNeverCalled(); + } + + /// + public void WasNeverCalled(string? message) + { + if (!_hasGetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a getter."); + } + + _engine.CreateVerification(_getterMemberId, $"get_{_propertyName}", + Array.Empty()).WasNeverCalled(message); + } + + /// + public void WasCalled() + { + if (!_hasGetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a getter."); + } + + _engine.CreateVerification(_getterMemberId, $"get_{_propertyName}", + Array.Empty()).WasCalled(); + } + + /// + public void WasCalled(string? message) + { + if (!_hasGetter) + { + throw new InvalidOperationException( + $"Property '{_propertyName}' does not have a getter."); + } + + _engine.CreateVerification(_getterMemberId, $"get_{_propertyName}", + Array.Empty()).WasCalled(message); + } +} + +/// +/// Unified return type for property setter calls with a specific value matcher. +/// Supports both setup (Callback, Throws) and verification (WasCalled, WasNeverCalled). +/// Eagerly registers the setup so that standalone calls (e.g., mock.Name.Set(Arg.Any<string>())) +/// work in strict mode without requiring chaining — matching the behavior of void method extensions. +/// Delegates to internally. +/// Public for generated code access. Not intended for direct use. +/// +/// The property type. +[EditorBrowsable(EditorBrowsableState.Never)] +public sealed class PropertySetterMockCall : ICallVerification +{ + private readonly VoidMockMethodCall _inner; + + /// Creates a new property setter mock call. + [EditorBrowsable(EditorBrowsableState.Never)] + public PropertySetterMockCall(IMockEngineAccess engine, int setterMemberId, + string propertyName, IArgumentMatcher matcher) + { + _inner = new VoidMockMethodCall(engine, setterMemberId, $"set_{propertyName}", + [matcher], eagerRegister: true); + } + + // --- Setup surface --- + + /// Execute a callback when the property setter is called with a matching value. + public PropertySetterMockCall Callback(Action callback) { _inner.Callback(callback); return this; } + + /// Configure the property setter to throw when called with a matching value. + public PropertySetterMockCall Throws() where TException : Exception, new() { _inner.Throws(); return this; } + + /// Configure the property setter to throw a specific exception when called with a matching value. + public PropertySetterMockCall Throws(Exception exception) { _inner.Throws(exception); return this; } + + // --- Verify surface --- + + /// + public void WasCalled(Times times) => _inner.WasCalled(times); + + /// + public void WasCalled(Times times, string? message) => _inner.WasCalled(times, message); + + /// + public void WasNeverCalled() => _inner.WasNeverCalled(); + + /// + public void WasNeverCalled(string? message) => _inner.WasNeverCalled(message); + + /// + public void WasCalled() => _inner.WasCalled(); + + /// + public void WasCalled(string? message) => _inner.WasCalled(message); +} diff --git a/TUnit.Mocks/Setup/PropertySetupAccessor.cs b/TUnit.Mocks/Setup/PropertySetupAccessor.cs deleted file mode 100644 index 3430245d8e..0000000000 --- a/TUnit.Mocks/Setup/PropertySetupAccessor.cs +++ /dev/null @@ -1,113 +0,0 @@ -using System.ComponentModel; -using TUnit.Mocks.Arguments; -using TUnit.Mocks.Matchers; - -namespace TUnit.Mocks.Setup; - -/// -/// Lightweight accessor for property setup. Returns from generated class members like -/// mock.Setup.Name. Lazily creates instances on demand. -/// -/// The property type. -[EditorBrowsable(EditorBrowsableState.Never)] -public readonly struct PropertySetupAccessor -{ - private readonly IMockEngineAccess _engine; - private readonly int _getterMemberId; - private readonly int _setterMemberId; - private readonly string _propertyName; - private readonly bool _hasGetter; - private readonly bool _hasSetter; - - /// Creates a new property setup accessor. - [EditorBrowsable(EditorBrowsableState.Never)] - public PropertySetupAccessor(IMockEngineAccess engine, int getterMemberId, int setterMemberId, - string propertyName, bool hasGetter, bool hasSetter) - { - _engine = engine; - _getterMemberId = getterMemberId; - _setterMemberId = setterMemberId; - _propertyName = propertyName; - _hasGetter = hasGetter; - _hasSetter = hasSetter; - } - - /// - /// Accesses the getter setup explicitly. Creates and registers a getter . - /// - public IPropertySetup Getter - { - get - { - if (!_hasGetter) - { - throw new InvalidOperationException( - $"Property '{_propertyName}' does not have a getter."); - } - - var matchers = Array.Empty(); - var methodSetup = new MethodSetup(_getterMemberId, matchers, $"{_propertyName} (get)"); - _engine.AddSetup(methodSetup); - return new PropertySetupBuilder(methodSetup); - } - } - - /// - /// Accesses the setter setup with any-value semantics. - /// Creates and registers a setter matching any argument. - /// - public IPropertySetterSetup Setter - { - get - { - if (!_hasSetter) - { - throw new InvalidOperationException( - $"Property '{_propertyName}' does not have a setter."); - } - - var matchers = Array.Empty(); - var methodSetup = new MethodSetup(_setterMemberId, matchers, $"{_propertyName} (set)"); - _engine.AddSetup(methodSetup); - return new PropertySetterSetupBuilder(methodSetup); - } - } - - /// - /// Accesses the setter setup with a specific value matcher. - /// Creates and registers a setter matching the specified value. - /// - public IPropertySetterSetup Set(Arg value) - { - if (!_hasSetter) - { - throw new InvalidOperationException( - $"Property '{_propertyName}' does not have a setter."); - } - - var matchers = new IArgumentMatcher[] { value.Matcher }; - var methodSetup = new MethodSetup(_setterMemberId, matchers, $"{_propertyName} (set)"); - _engine.AddSetup(methodSetup); - return new PropertySetterSetupBuilder(methodSetup); - } - - // Convenience shortcuts that delegate to Getter - - /// Configure a fixed return value for the property getter. - public ISetupChain Returns(TProperty value) => Getter.Returns(value); - - /// Configure a computed return value for the property getter. - public ISetupChain Returns(Func factory) => Getter.Returns(factory); - - /// Configure sequential return values for the property getter. - public ISetupChain ReturnsSequentially(params TProperty[] values) => Getter.ReturnsSequentially(values); - - /// Configure the property getter to throw. - public ISetupChain Throws() where TException : Exception, new() => Getter.Throws(); - - /// Configure the property getter to throw a specific exception. - public ISetupChain Throws(Exception exception) => Getter.Throws(exception); - - /// Execute a callback when the property getter is called. - public ISetupChain Callback(Action callback) => Getter.Callback(callback); -} diff --git a/TUnit.Mocks/Verification/PropertyVerifyAccessor.cs b/TUnit.Mocks/Verification/PropertyVerifyAccessor.cs deleted file mode 100644 index 9481e4494f..0000000000 --- a/TUnit.Mocks/Verification/PropertyVerifyAccessor.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System.ComponentModel; -using TUnit.Mocks.Arguments; -using TUnit.Mocks.Matchers; - -namespace TUnit.Mocks.Verification; - -/// -/// Lightweight accessor for property verification. Returns from generated class members like -/// mock.Verify.Name. Lazily creates verification builders on demand. -/// Implements to allow mock.Verify.Name.WasCalled(...) directly -/// (delegates to getter verification). -/// -/// The property type. -[EditorBrowsable(EditorBrowsableState.Never)] -public readonly struct PropertyVerifyAccessor : ICallVerification -{ - private readonly IMockEngineAccess _engine; - private readonly int _getterMemberId; - private readonly int _setterMemberId; - private readonly string _propertyName; - private readonly bool _hasGetter; - private readonly bool _hasSetter; - - /// Creates a new property verify accessor. - [EditorBrowsable(EditorBrowsableState.Never)] - public PropertyVerifyAccessor(IMockEngineAccess engine, int getterMemberId, int setterMemberId, - string propertyName, bool hasGetter, bool hasSetter) - { - _engine = engine; - _getterMemberId = getterMemberId; - _setterMemberId = setterMemberId; - _propertyName = propertyName; - _hasGetter = hasGetter; - _hasSetter = hasSetter; - } - - /// - /// Accesses the getter verification explicitly. - /// - public ICallVerification Getter - { - get - { - if (!_hasGetter) - { - throw new InvalidOperationException( - $"Property '{_propertyName}' does not have a getter."); - } - - return _engine.CreateVerification(_getterMemberId, $"get_{_propertyName}", - Array.Empty()); - } - } - - /// - /// Accesses the setter verification with any-value semantics. - /// - public ICallVerification Setter - { - get - { - if (!_hasSetter) - { - throw new InvalidOperationException( - $"Property '{_propertyName}' does not have a setter."); - } - - return _engine.CreateVerification(_setterMemberId, $"set_{_propertyName}", - Array.Empty()); - } - } - - /// - /// Accesses the setter verification with a specific value matcher. - /// - public ICallVerification Set(Arg value) - { - if (!_hasSetter) - { - throw new InvalidOperationException( - $"Property '{_propertyName}' does not have a setter."); - } - - return _engine.CreateVerification(_setterMemberId, $"set_{_propertyName}", - new IArgumentMatcher[] { value.Matcher }); - } - - // ICallVerification implementation — delegates to Getter - - /// - public void WasCalled(Times times) => Getter.WasCalled(times); - - /// - public void WasCalled(Times times, string? message) => Getter.WasCalled(times, message); - - /// - public void WasNeverCalled() => Getter.WasNeverCalled(); - - /// - public void WasNeverCalled(string? message) => Getter.WasNeverCalled(message); - - /// - public void WasCalled() => Getter.WasCalled(); - - /// - public void WasCalled(string? message) => Getter.WasCalled(message); -} diff --git a/TUnit.Mocks/VoidMockMethodCall.cs b/TUnit.Mocks/VoidMockMethodCall.cs new file mode 100644 index 0000000000..2df33a2ea5 --- /dev/null +++ b/TUnit.Mocks/VoidMockMethodCall.cs @@ -0,0 +1,145 @@ +using System.ComponentModel; +using TUnit.Mocks.Arguments; +using TUnit.Mocks.Setup; +using TUnit.Mocks.Verification; + +namespace TUnit.Mocks; + +/// +/// Unified return type for void mock method calls. Supports both setup and verification. +/// When eagerRegister is true (the default for extension methods on Mock<T>), +/// the setup is registered in the constructor so that standalone calls like +/// mock.Log(Arg.Any<string>()) work in strict mode without chaining. +/// When eagerRegister is false (used by ), +/// registration is deferred until a setup method is explicitly called, avoiding unwanted +/// setup side-effects when the object is used purely for verification. +/// Public for generated code access. Not intended for direct use. +/// +[EditorBrowsable(EditorBrowsableState.Never)] +public sealed class VoidMockMethodCall : IVoidMethodSetup, IVoidSetupChain, ICallVerification +{ + private readonly IMockEngineAccess _engine; + private readonly int _memberId; + private readonly string _memberName; + private readonly IArgumentMatcher[] _matchers; + private readonly Lazy _lazyBuilder; + + [EditorBrowsable(EditorBrowsableState.Never)] + public VoidMockMethodCall(IMockEngineAccess engine, int memberId, string memberName, IArgumentMatcher[] matchers) + : this(engine, memberId, memberName, matchers, eagerRegister: true) + { + } + + [EditorBrowsable(EditorBrowsableState.Never)] + internal VoidMockMethodCall(IMockEngineAccess engine, int memberId, string memberName, IArgumentMatcher[] matchers, bool eagerRegister) + { + _engine = engine; + _memberId = memberId; + _memberName = memberName; + _matchers = matchers; + _lazyBuilder = new Lazy(() => + { + var setup = new MethodSetup(_memberId, _matchers, _memberName); + _engine.AddSetup(setup); + return new VoidMethodSetupBuilder(setup); + }); + if (eagerRegister) + { + _ = _lazyBuilder.Value; + } + } + + private VoidMethodSetupBuilder EnsureSetup() => _lazyBuilder.Value; + + // IVoidMethodSetup implementation + + public IVoidSetupChain Throws() where TException : Exception, new() + { + EnsureSetup().Throws(); + return this; + } + + public IVoidSetupChain Throws(Exception exception) + { + EnsureSetup().Throws(exception); + return this; + } + + public IVoidSetupChain Callback(Action callback) + { + EnsureSetup().Callback(callback); + return this; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public IVoidSetupChain Callback(Action callback) + { + EnsureSetup().Callback(callback); + return this; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public IVoidSetupChain Throws(Func exceptionFactory) + { + EnsureSetup().Throws(exceptionFactory); + return this; + } + + public IVoidSetupChain Raises(string eventName, object? args = null) + { + EnsureSetup().Raises(eventName, args); + return this; + } + + public IVoidSetupChain SetsOutParameter(int paramIndex, object? value) + { + EnsureSetup().SetsOutParameter(paramIndex, value); + return this; + } + + public IVoidSetupChain TransitionsTo(string stateName) + { + EnsureSetup().TransitionsTo(stateName); + return this; + } + + // IVoidSetupChain implementation + + public IVoidMethodSetup Then() + { + EnsureSetup().Then(); + return this; + } + + // ICallVerification implementation + + public void WasCalled(Times times) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times); + } + + public void WasCalled(Times times, string? message) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message); + } + + public void WasNeverCalled() + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(); + } + + public void WasNeverCalled(string? message) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message); + } + + public void WasCalled() + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(); + } + + public void WasCalled(string? message) + { + _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message); + } +} diff --git a/docs/docs/test-authoring/mocking/advanced.md b/docs/docs/test-authoring/mocking/advanced.md index 5e1ec4c1b1..e5b4a71f76 100644 --- a/docs/docs/test-authoring/mocking/advanced.md +++ b/docs/docs/test-authoring/mocking/advanced.md @@ -8,7 +8,7 @@ sidebar_position: 5 ### Raising Events -If the mocked interface declares events, TUnit.Mocks generates a `Raise` surface: +If the mocked interface declares events, TUnit.Mocks generates `Raise{EventName}()` extension methods directly on `Mock`: ```csharp public interface IConnection @@ -24,7 +24,7 @@ string? received = null; mock.Object.OnMessage += (sender, msg) => received = msg; // Raise the event through the mock -mock.Raise.OnMessage("Hello!"); +mock.RaiseOnMessage("Hello!"); // received == "Hello!" ``` @@ -33,7 +33,7 @@ mock.Raise.OnMessage("Hello!"); Trigger an event automatically when a method is called using the typed `.Raises{EventName}()` method on a setup chain: ```csharp -mock.Setup.SendMessage(Arg.Any()) +mock.SendMessage(Arg.Any()) .RaisesOnMessage("echo"); mock.Object.SendMessage("test"); @@ -76,16 +76,16 @@ public interface IConnection var mock = Mock.Of(); mock.SetState("disconnected"); -mock.InState("disconnected", setup => +mock.InState("disconnected", m => { - setup.GetStatus().Returns("OFFLINE"); - setup.Connect().TransitionsTo("connected"); + m.GetStatus().Returns("OFFLINE"); + m.Connect().TransitionsTo("connected"); }); -mock.InState("connected", setup => +mock.InState("connected", m => { - setup.GetStatus().Returns("ONLINE"); - setup.Disconnect().TransitionsTo("disconnected"); + m.GetStatus().Returns("ONLINE"); + m.Disconnect().TransitionsTo("disconnected"); }); // Start disconnected @@ -130,7 +130,7 @@ var serviceB = mock.Object.GetServiceB(); // Configure the auto-mock var autoMock = mock.GetAutoMock("GetServiceB"); -autoMock.Setup.GetValue().Returns(42); +autoMock.GetValue().Returns(42); var value = serviceB.GetValue(); // 42 ``` @@ -148,8 +148,8 @@ var serviceMock = repo.Of(); var loggerMock = repo.Of(); // Configure each mock individually -serviceMock.Setup.GetData(Arg.Any()).Returns("result"); -loggerMock.Setup.Log(Arg.Any()); +serviceMock.GetData(Arg.Any()).Returns("result"); +loggerMock.Log(Arg.Any()); // Exercise code serviceMock.Object.GetData(1); @@ -181,8 +181,8 @@ repo.Reset(); // clear all mocks Get a diagnostic report of setup coverage and call matching: ```csharp -mock.Setup.GetUser(Arg.Any()).Returns(new User("Alice")); -mock.Setup.Delete(Arg.Any()); +mock.GetUser(Arg.Any()).Returns(new User("Alice")); +mock.Delete(Arg.Any()); svc.GetUser(1); // Delete was never called @@ -228,7 +228,7 @@ The provider is consulted **before** auto-mocking and built-in smart defaults. Clear all setups, call history, state, and auto-tracked property values: ```csharp -mock.Setup.GetUser(Arg.Any()).Returns(new User("Alice")); +mock.GetUser(Arg.Any()).Returns(new User("Alice")); svc.GetUser(1); mock.Reset(); diff --git a/docs/docs/test-authoring/mocking/argument-matchers.md b/docs/docs/test-authoring/mocking/argument-matchers.md index fe16cb9fd7..f41fc10af2 100644 --- a/docs/docs/test-authoring/mocking/argument-matchers.md +++ b/docs/docs/test-authoring/mocking/argument-matchers.md @@ -4,7 +4,7 @@ sidebar_position: 4 # Argument Matchers -Argument matchers control which calls a setup or verification matches. They are used in both `mock.Setup` and `mock.Verify` surfaces. +Argument matchers control which calls a setup or verification matches. The same matchers work in both contexts — the chain method determines whether it's a setup or verification. ## Quick Reference @@ -33,7 +33,7 @@ Argument matchers control which calls a setup or verification matches. They are Matches any value, including null: ```csharp -mock.Setup.GetUser(Arg.Any()).Returns(new User("Default")); +mock.GetUser(Arg.Any()).Returns(new User("Default")); svc.GetUser(1); // matches svc.GetUser(999); // matches @@ -44,8 +44,8 @@ svc.GetUser(999); // matches Match a specific value using equality: ```csharp -mock.Setup.GetUser(Arg.Is(42)).Returns(new User("Alice")); -mock.Setup.GetUser(Arg.Is(99)).Returns(new User("Bob")); +mock.GetUser(Arg.Is(42)).Returns(new User("Alice")); +mock.GetUser(Arg.Is(99)).Returns(new User("Bob")); svc.GetUser(42); // returns Alice svc.GetUser(99); // returns Bob @@ -55,8 +55,8 @@ svc.GetUser(1); // no match — returns default :::tip Implicit Conversion Raw values are implicitly converted to `Arg.Is(value)`, so these are equivalent: ```csharp -mock.Setup.GetUser(Arg.Is(42)).Returns(new User("Alice")); -mock.Setup.GetUser(42).Returns(new User("Alice")); // same thing +mock.GetUser(Arg.Is(42)).Returns(new User("Alice")); +mock.GetUser(42).Returns(new User("Alice")); // same thing ``` ::: @@ -65,15 +65,15 @@ mock.Setup.GetUser(42).Returns(new User("Alice")); // same thing Match values satisfying a condition: ```csharp -mock.Setup.GetUser(Arg.Is(id => id > 0)).Returns(new User("Valid")); -mock.Setup.GetUser(Arg.Is(id => id <= 0)).Throws(); +mock.GetUser(Arg.Is(id => id > 0)).Returns(new User("Valid")); +mock.GetUser(Arg.Is(id => id <= 0)).Throws(); ``` ### Null and NotNull ```csharp -mock.Setup.Process(Arg.IsNull()).Returns("was null"); -mock.Setup.Process(Arg.IsNotNull()).Returns("had value"); +mock.Process(Arg.IsNull()).Returns("was null"); +mock.Process(Arg.IsNotNull()).Returns("had value"); ``` ## String Matchers @@ -82,7 +82,7 @@ mock.Setup.Process(Arg.IsNotNull()).Returns("had value"); ```csharp // Match strings against a regex pattern -mock.Setup.Search(Arg.Matches(@"^user_\d+$")).Returns(new[] { "found" }); +mock.Search(Arg.Matches(@"^user_\d+$")).Returns(new[] { "found" }); svc.Search("user_42"); // matches svc.Search("admin_1"); // no match @@ -92,7 +92,7 @@ svc.Search("admin_1"); // no match ```csharp var pattern = new Regex(@"^user_\d+$", RegexOptions.Compiled); -mock.Setup.Search(Arg.Matches(pattern)).Returns(new[] { "found" }); +mock.Search(Arg.Matches(pattern)).Returns(new[] { "found" }); ``` ## Collection Matchers @@ -100,7 +100,7 @@ mock.Setup.Search(Arg.Matches(pattern)).Returns(new[] { "found" }); ### Contains ```csharp -mock.Setup.ProcessItems(Arg.Contains, int>(42)).Returns(true); +mock.ProcessItems(Arg.Contains, int>(42)).Returns(true); svc.ProcessItems(new List { 1, 42, 3 }); // matches — contains 42 svc.ProcessItems(new List { 1, 2, 3 }); // no match @@ -109,7 +109,7 @@ svc.ProcessItems(new List { 1, 2, 3 }); // no match ### HasCount ```csharp -mock.Setup.ProcessItems(Arg.HasCount>(3)).Returns(true); +mock.ProcessItems(Arg.HasCount>(3)).Returns(true); svc.ProcessItems(new List { 1, 2, 3 }); // matches — count is 3 svc.ProcessItems(new List { 1, 2 }); // no match @@ -118,7 +118,7 @@ svc.ProcessItems(new List { 1, 2 }); // no match ### IsEmpty ```csharp -mock.Setup.ProcessItems(Arg.IsEmpty>()).Returns(false); +mock.ProcessItems(Arg.IsEmpty>()).Returns(false); svc.ProcessItems(new List()); // matches svc.ProcessItems(new List { 1 }); // no match @@ -127,7 +127,7 @@ svc.ProcessItems(new List { 1 }); // no match ### SequenceEquals ```csharp -mock.Setup.ProcessItems( +mock.ProcessItems( Arg.SequenceEquals, int>(new[] { 1, 2, 3 }) ).Returns(true); @@ -140,7 +140,7 @@ svc.ProcessItems(new List { 3, 2, 1 }); // no match — wrong order ### IsInRange ```csharp -mock.Setup.SetAge(Arg.IsInRange(0, 120)).Returns(true); +mock.SetAge(Arg.IsInRange(0, 120)).Returns(true); svc.SetAge(25); // matches svc.SetAge(-1); // no match @@ -150,8 +150,8 @@ svc.SetAge(200); // no match ### IsIn / IsNotIn ```csharp -mock.Setup.GetRole(Arg.IsIn("admin", "editor", "viewer")).Returns(true); -mock.Setup.GetRole(Arg.IsNotIn("admin", "superadmin")).Returns(false); +mock.GetRole(Arg.IsIn("admin", "editor", "viewer")).Returns(true); +mock.GetRole(Arg.IsNotIn("admin", "superadmin")).Returns(false); ``` ## Negation @@ -159,7 +159,7 @@ mock.Setup.GetRole(Arg.IsNotIn("admin", "superadmin")).Returns(false); Wrap any matcher with `Not` to invert it: ```csharp -mock.Setup.Process(Arg.Not(Arg.Is(0))).Returns("non-zero"); +mock.Process(Arg.Not(Arg.Is(0))).Returns("non-zero"); // Matches any int except 0 ``` @@ -169,7 +169,7 @@ Every `Arg` matcher automatically captures the values it sees: ```csharp var nameArg = Arg.Any(); -mock.Setup.Greet(nameArg).Returns("Hi"); +mock.Greet(nameArg).Returns("Hi"); svc.Greet("Alice"); svc.Greet("Bob"); @@ -213,7 +213,7 @@ public class StringLengthMatcher : IArgumentMatcher } // Usage -mock.Setup.Greet(Arg.Matches(new StringLengthMatcher(3, 50))) +mock.Greet(Arg.Matches(new StringLengthMatcher(3, 50))) .Returns("Valid name"); ``` diff --git a/docs/docs/test-authoring/mocking/index.md b/docs/docs/test-authoring/mocking/index.md index ddfa24e29a..8b04b71633 100644 --- a/docs/docs/test-authoring/mocking/index.md +++ b/docs/docs/test-authoring/mocking/index.md @@ -48,7 +48,7 @@ public class GreeterTests var mock = Mock.Of(); // Configure — set up a return value - mock.Setup.Greet(Arg.Any()).Returns("Hello!"); + mock.Greet(Arg.Any()).Returns("Hello!"); // Act — use the mock object IGreeter greeter = mock.Object; @@ -56,7 +56,7 @@ public class GreeterTests // Assert — verify the result and the call await Assert.That(result).IsEqualTo("Hello!"); - mock.Verify.Greet("Alice").WasCalled(Times.Once); + mock.Greet("Alice").WasCalled(Times.Once); } } ``` @@ -86,15 +86,15 @@ var strict = Mock.Of(MockBehavior.Strict); // throws on unconfigured ### The Mock Wrapper -`Mock.Of()` returns a `Mock` wrapper with three surfaces: +`Mock.Of()` returns a `Mock` wrapper. Extension methods are generated directly on `Mock` for each member of the mocked type, and the chain methods (`.Returns()`, `.WasCalled()`, etc.) disambiguate between setup and verification: ```csharp var mock = Mock.Of(); -mock.Setup // configure method/property behaviors -mock.Verify // verify calls were made -mock.Raise // raise events (if T has events) -mock.Object // the T instance to pass to your code under test +mock.GetUser(Arg.Any()).Returns(user); // setup — .Returns() makes it a stub +mock.GetUser(42).WasCalled(Times.Once); // verify — .WasCalled() makes it a check +mock.RaiseOnMessage("hi"); // raise events — Raise{EventName}() +mock.Object // the T instance to pass to your code under test ``` ### Implicit Conversion diff --git a/docs/docs/test-authoring/mocking/setup.md b/docs/docs/test-authoring/mocking/setup.md index 29007d0055..579651d467 100644 --- a/docs/docs/test-authoring/mocking/setup.md +++ b/docs/docs/test-authoring/mocking/setup.md @@ -4,7 +4,7 @@ sidebar_position: 2 # Setup & Stubbing -The `mock.Setup` surface configures how the mock responds when its members are called. +Methods are called directly on `Mock` — the chain method (`.Returns()`, `.Throws()`, etc.) makes it a setup. ## Method Setup @@ -12,13 +12,13 @@ The `mock.Setup` surface configures how the mock responds when its members are c ```csharp // Fixed return value -mock.Setup.GetUser(Arg.Any()).Returns(new User("Alice")); +mock.GetUser(Arg.Any()).Returns(new User("Alice")); // Computed return value -mock.Setup.GetUser(Arg.Any()).Returns(() => new User(DateTime.Now.ToString())); +mock.GetUser(Arg.Any()).Returns(() => new User(DateTime.Now.ToString())); // Async methods — no special API needed -mock.Setup.GetUserAsync(Arg.Any()).Returns(new User("Alice")); +mock.GetUserAsync(Arg.Any()).Returns(new User("Alice")); // TUnit.Mocks auto-wraps the value in Task or ValueTask ``` @@ -26,10 +26,10 @@ mock.Setup.GetUserAsync(Arg.Any()).Returns(new User("Alice")); ```csharp // Throw a specific exception type -mock.Setup.Delete(Arg.Any()).Throws(); +mock.Delete(Arg.Any()).Throws(); // Throw a specific instance -mock.Setup.Delete(Arg.Any()).Throws(new ArgumentException("bad id")); +mock.Delete(Arg.Any()).Throws(new ArgumentException("bad id")); ``` ### Callbacks @@ -37,11 +37,11 @@ mock.Setup.Delete(Arg.Any()).Throws(new ArgumentException("bad id")); ```csharp // Simple callback var callCount = 0; -mock.Setup.Process(Arg.Any()) +mock.Process(Arg.Any()) .Callback(() => callCount++); // Callback with access to arguments -mock.Setup.Process(Arg.Any()) +mock.Process(Arg.Any()) .Callback((object?[] args) => Console.WriteLine($"Called with: {args[0]}")); ``` @@ -50,7 +50,7 @@ mock.Setup.Process(Arg.Any()) Use `.Then()` to define different behaviors for successive calls: ```csharp -mock.Setup.GetValue(Arg.Any()) +mock.GetValue(Arg.Any()) .Throws() // 1st call: throws .Then() .Returns("retry-succeeded") // 2nd call: returns value @@ -58,7 +58,7 @@ mock.Setup.GetValue(Arg.Any()) .Returns("cached"); // 3rd+ calls: returns this value // Shorthand for sequential return values -mock.Setup.GetValue(Arg.Any()) +mock.GetValue(Arg.Any()) .ReturnsSequentially("first", "second", "third"); // 1st: "first", 2nd: "second", 3rd+: "third" (last value repeats) ``` @@ -68,13 +68,15 @@ mock.Setup.GetValue(Arg.Any()) Void methods support `Callback` and `Throws` (but not `Returns`): ```csharp -mock.Setup.Log(Arg.Any()) +mock.Log(Arg.Any()) .Callback(() => { /* side effect */ }); -mock.Setup.Log(Arg.Any()) +mock.Log(Arg.Any()) .Throws(); ``` +Void methods are also eagerly registered — calling `mock.Log(Arg.Any())` without chaining is sufficient to "allow" the call in strict mode. + ## Property Setup TUnit.Mocks uses C# 14 extension properties for a natural property API. The default behavior targets the **getter** (the most common case). @@ -83,29 +85,29 @@ TUnit.Mocks uses C# 14 extension properties for a natural property API. The defa ```csharp // These are equivalent — both configure the getter -mock.Setup.Name.Returns("Alice"); -mock.Setup.Name.Getter.Returns("Alice"); +mock.Name.Returns("Alice"); +mock.Name.Getter.Returns("Alice"); ``` All method setup operations work on getters: ```csharp -mock.Setup.Name.Throws(); -mock.Setup.Name.Callback(() => Console.WriteLine("Name accessed")); -mock.Setup.Name.ReturnsSequentially("first", "second"); +mock.Name.Throws(); +mock.Name.Callback(() => Console.WriteLine("Name accessed")); +mock.Name.ReturnsSequentially("first", "second"); ``` ### Setter Setup ```csharp // React to any value being set -mock.Setup.Count.Setter.Callback(() => Console.WriteLine("Count was set")); +mock.Count.Setter.Callback(() => Console.WriteLine("Count was set")); // React to a specific value being set -mock.Setup.Count.Set(Arg.Is(42)).Callback(() => Console.WriteLine("Count set to 42")); +mock.Count.Set(Arg.Is(42)).Callback(() => Console.WriteLine("Count set to 42")); // Throw on setter -mock.Setup.Name.Setter.Throws(); +mock.Name.Setter.Throws(); ``` ### Auto-Tracking Properties @@ -127,18 +129,32 @@ Explicit setups take precedence over auto-tracked values. ## Out and Ref Parameters -**Out parameters** are excluded from setup signatures. Use `.SetsOutParameter()` to assign their values: +**Out parameters** are excluded from setup signatures. Use the generated strongly-typed `.SetsOut{Name}()` methods to assign their values: ```csharp -mock.Setup.TryGet("key") +// Strongly-typed — named after the parameter, compile-time safe +mock.TryGet("key") .Returns(true) - .SetsOutParameter(0, "found-value"); // paramIndex 0 = first out param + .SetsOutValue("found-value"); bool found = svc.TryGet("key", out var value); // found == true, value == "found-value" ``` -**Ref parameters** are included in setup signatures and participate in argument matching. +**Ref parameters** are included in setup signatures and participate in argument matching. Use `.SetsRef{Name}()` to assign output values: + +```csharp +mock.Swap(Arg.Any()) + .SetsRefValue(99); + +int val = 42; +svc.Swap(ref val); +// val == 99 +``` + +The method names are derived from the original parameter names — e.g. `out string value` produces `.SetsOutValue()`, `ref int count` produces `.SetsRefCount()`. This gives you IntelliSense discoverability and compile-time type safety. + +The untyped `.SetsOutParameter(index, value)` overload remains available for advanced scenarios but is hidden from IntelliSense on typed wrappers. ## Partial Mocks @@ -152,7 +168,7 @@ public abstract class Calculator } var mock = Mock.OfPartial(); -mock.Setup.Multiply(Arg.Any(), Arg.Any()).Returns(99); +mock.Multiply(Arg.Any(), Arg.Any()).Returns(99); mock.Object.Add(2, 3); // 5 (base implementation) mock.Object.Multiply(2, 3); // 99 (mocked) @@ -170,7 +186,7 @@ Mock any delegate type: ```csharp var mock = Mock.OfDelegate>(); -mock.Setup.Invoke(Arg.Any()).Returns(42); +mock.Invoke(Arg.Any()).Returns(42); Func func = mock; var result = func("hello"); // 42 @@ -187,7 +203,7 @@ var realService = new ProductionService(); var mock = Mock.Wrap(realService); // Override just one method -mock.Setup.GetConfig().Returns(new TestConfig()); +mock.GetConfig().Returns(new TestConfig()); // All other calls go to realService mock.Object.DoWork(); // calls realService.DoWork() @@ -200,7 +216,7 @@ Create a single mock that implements multiple interfaces: ```csharp var mock = Mock.Of(); -mock.Setup.Log(Arg.Any()); // ILogger method +mock.Log(Arg.Any()); // ILogger method mock.Object.Log("test"); ((IDisposable)mock.Object).Dispose(); // IDisposable method @@ -213,7 +229,7 @@ Supports up to 4 interfaces: `Mock.Of()`. Setup methods return chain objects that support additional behaviors: ```csharp -mock.Setup.Process(Arg.Any()) +mock.Process(Arg.Any()) .Returns(true) .RaisesProcessCompleted(EventArgs.Empty) // strongly-typed auto-raise event .TransitionsTo("processed"); // state machine transition diff --git a/docs/docs/test-authoring/mocking/verification.md b/docs/docs/test-authoring/mocking/verification.md index 41d7ab842f..f49041368b 100644 --- a/docs/docs/test-authoring/mocking/verification.md +++ b/docs/docs/test-authoring/mocking/verification.md @@ -4,19 +4,19 @@ sidebar_position: 3 # Verification -The `mock.Verify` surface checks that expected calls were made to the mock. +Verification uses the same methods as setup — the chain method (`.WasCalled()`, `.WasNeverCalled()`) makes it a verification instead of a setup. ## Basic Verification ```csharp // Verify a method was called at least once -mock.Verify.GetUser(42).WasCalled(); +mock.GetUser(42).WasCalled(); // Verify exact call count -mock.Verify.GetUser(42).WasCalled(Times.Once); +mock.GetUser(42).WasCalled(Times.Once); // Verify never called -mock.Verify.Delete(Arg.Any()).WasNeverCalled(); +mock.Delete(Arg.Any()).WasNeverCalled(); ``` ### Times @@ -34,8 +34,8 @@ mock.Verify.Delete(Arg.Any()).WasNeverCalled(); ### Custom Failure Messages ```csharp -mock.Verify.GetUser(42).WasCalled(Times.Once, "GetUser should be called once during initialization"); -mock.Verify.Delete(Arg.Any()).WasNeverCalled("Delete should not be called in read-only mode"); +mock.GetUser(42).WasCalled(Times.Once, "GetUser should be called once during initialization"); +mock.Delete(Arg.Any()).WasNeverCalled("Delete should not be called in read-only mode"); ``` ## Property Verification @@ -44,17 +44,17 @@ Property verification mirrors the setup API — defaults to the **getter**: ```csharp // Getter verification -mock.Verify.Name.WasCalled(Times.Once); // getter called once -mock.Verify.Name.Getter.WasCalled(Times.Once); // explicit — same as above -mock.Verify.Name.WasNeverCalled(); // getter never accessed +mock.Name.WasCalled(Times.Once); // getter called once +mock.Name.Getter.WasCalled(Times.Once); // explicit — same as above +mock.Name.WasNeverCalled(); // getter never accessed // Setter verification — any value -mock.Verify.Count.Setter.WasCalled(Times.Exactly(3)); -mock.Verify.Count.Setter.WasNeverCalled(); +mock.Count.Setter.WasCalled(Times.Exactly(3)); +mock.Count.Setter.WasNeverCalled(); // Setter verification — specific value -mock.Verify.Count.Set(42).WasCalled(Times.Once); -mock.Verify.Count.Set(Arg.Is(v => v > 0)).WasCalled(Times.AtLeast(1)); +mock.Count.Set(42).WasCalled(Times.Once); +mock.Count.Set(Arg.Is(v => v > 0)).WasCalled(Times.AtLeast(1)); ``` ## Argument Matching in Verification @@ -63,13 +63,13 @@ Verification uses the same `Arg` matchers as setup: ```csharp // Exact value -mock.Verify.GetUser(42).WasCalled(Times.Once); +mock.GetUser(42).WasCalled(Times.Once); // Any value -mock.Verify.GetUser(Arg.Any()).WasCalled(Times.Exactly(3)); +mock.GetUser(Arg.Any()).WasCalled(Times.Exactly(3)); // Predicate -mock.Verify.GetUser(Arg.Is(id => id > 0)).WasCalled(Times.AtLeast(1)); +mock.GetUser(Arg.Is(id => id > 0)).WasCalled(Times.AtLeast(1)); ``` See [Argument Matchers](argument-matchers) for the full list of matchers. @@ -81,9 +81,9 @@ Verify calls occurred in a specific order **across one or more mocks**: ```csharp Mock.VerifyInOrder(() => { - mockLogger.Verify.Log("Starting").WasCalled(); - mockRepo.Verify.SaveAsync(Arg.Any()).WasCalled(); - mockLogger.Verify.Log("Done").WasCalled(); + mockLogger.Log("Starting").WasCalled(); + mockRepo.SaveAsync(Arg.Any()).WasCalled(); + mockLogger.Log("Done").WasCalled(); }); ``` @@ -98,8 +98,8 @@ If calls occurred out of order, `VerifyInOrder` throws with a message showing th Verify that **every setup** was invoked at least once: ```csharp -mock.Setup.GetUser(Arg.Any()).Returns(new User("Alice")); -mock.Setup.Delete(Arg.Any()); +mock.GetUser(Arg.Any()).Returns(new User("Alice")); +mock.Delete(Arg.Any()); svc.GetUser(1); svc.Delete(2); @@ -117,8 +117,8 @@ Verify that all recorded calls have been explicitly verified: svc.GetUser(1); svc.Delete(2); -mock.Verify.GetUser(1).WasCalled(Times.Once); -mock.Verify.Delete(2).WasCalled(Times.Once); +mock.GetUser(1).WasCalled(Times.Once); +mock.Delete(2).WasCalled(Times.Once); mock.VerifyNoOtherCalls(); // passes — all calls accounted for ``` @@ -132,11 +132,11 @@ Use TUnit's `Assert.That` pipeline for assertion-style verification with better ```csharp using TUnit.Mocks.Assertions; -await Assert.That(mock.Verify.GetUser(42)).WasCalled(Times.Once); -await Assert.That(mock.Verify.Delete(Arg.Any())).WasNeverCalled(); +await Assert.That(mock.GetUser(42)).WasCalled(Times.Once); +await Assert.That(mock.Delete(Arg.Any())).WasNeverCalled(); // Property verification through assertions -await Assert.That(mock.Verify.Name).WasCalled(Times.Once); +await Assert.That(mock.Name).WasCalled(Times.Once); ``` This integrates with TUnit's assertion engine — failures appear as assertion errors with expression trees in the output.