Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
d02862f
feat(mocks): add MockMethodCall<TReturn> and VoidMockMethodCall unifi…
thomhurst Feb 23, 2026
88d5d29
feat(mocks): add PropertyMockCall<TProperty> and PropertySetterMockCa…
thomhurst Feb 23, 2026
9e29594
feat(mocks): simplify Mock<T> by removing Setup/Verify/Raise surfaces
thomhurst Feb 23, 2026
4ac0258
feat(mocks): replace MockSetupBuilder + MockVerifyBuilder with unifie…
thomhurst Feb 23, 2026
05814e9
refactor: update RaiseBuilder and factory builders for simplified Moc…
thomhurst Feb 23, 2026
d0a70f0
refactor(mocks): update all test files for unified Mock<T> API
thomhurst Feb 23, 2026
ff689f0
fix(mocks): eagerly register void method and property setter setups
thomhurst Feb 23, 2026
c41427e
docs: update mocking documentation for unified Mock<T> API
thomhurst Feb 23, 2026
f225a2c
fix(mocks): use Lazy<T> for thread-safe setup registration in non-voi…
thomhurst Feb 23, 2026
f5f06f4
fix(mocks): address review feedback — member names, setter registrati…
thomhurst Feb 23, 2026
78c57a3
fix(mocks): use Lazy<T> in PropertySetterMockCall for consistency
thomhurst Feb 23, 2026
c6690cc
fix(mocks): cache matchers/name in PropertySetterMockCall, clarify ge…
thomhurst Feb 23, 2026
7db470f
feat(mocks): generate strongly-typed SetsOut/SetsRef methods for out/…
thomhurst Feb 23, 2026
9346b08
fix(mocks): address review feedback — attribute ordering, modern syntax
thomhurst Feb 23, 2026
f7495b3
fix(mocks): eliminate PropertySetterMockCall duplication, consolidate…
thomhurst Feb 23, 2026
42b8448
fix(mocks): document eager registration rationale on PropertySetterMo…
thomhurst Feb 23, 2026
b603826
fix(mocks): use Lazy<T> in generated void wrapper classes for thread …
thomhurst Feb 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions TUnit.Mocks.Assertions/MockAssertionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace TUnit.Mocks.Assertions;

/// <summary>
/// Extension methods for asserting mock call verification through the TUnit assertion pipeline.
/// Enables: <c>await Assert.That(mock.Verify.Method()).WasCalled(Times.Once);</c>
/// Enables: <c>await Assert.That(mock.Method()).WasCalled(Times.Once);</c>
/// </summary>
public static class MockAssertionExtensions
{
Expand All @@ -24,7 +24,7 @@ public static WasCalledAssertion WasCalled(

/// <summary>
/// Asserts that the mock member was called the specified number of times.
/// Generic overload for types implementing <see cref="ICallVerification"/> (e.g. PropertyVerifyAccessor).
/// Generic overload for types implementing <see cref="ICallVerification"/> (e.g. PropertyMockCall).
/// </summary>
public static WasCalledAssertion WasCalled<T>(
this IAssertionSource<T> source,
Expand All @@ -48,7 +48,7 @@ public static WasNeverCalledAssertion WasNeverCalled(

/// <summary>
/// Asserts that the mock member was never called.
/// Generic overload for types implementing <see cref="ICallVerification"/> (e.g. PropertyVerifyAccessor).
/// Generic overload for types implementing <see cref="ICallVerification"/> (e.g. PropertyMockCall).
/// </summary>
public static WasNeverCalledAssertion WasNeverCalled<T>(
this IAssertionSource<T> source) where T : ICallVerification
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ namespace TUnit.Mocks.Generated
var engine = new global::TUnit.Mocks.MockEngine<global::IReadWriter>(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<global::IReadWriter>(impl, setup, verify, engine);
var mock = new global::TUnit.Mocks.Mock<global::IReadWriter>(impl, engine);
return mock;
}
}
Expand Down Expand Up @@ -72,121 +70,99 @@ namespace TUnit.Mocks.Generated

namespace TUnit.Mocks.Generated
{
public sealed class IReadWriter_MockSetup : global::TUnit.Mocks.IMockSetup<global::IReadWriter>
public static class IReadWriter_MockMemberExtensions
{
internal readonly global::TUnit.Mocks.MockEngine<global::IReadWriter> Engine;

internal IReadWriter_MockSetup(global::TUnit.Mocks.MockEngine<global::IReadWriter> engine) => Engine = engine;
}

public static class IReadWriter_MockSetupExtensions
{
public static global::TUnit.Mocks.Setup.IVoidMethodSetup Flush(this global::TUnit.Mocks.IMockSetup<global::IReadWriter> setup)
public static global::TUnit.Mocks.VoidMockMethodCall Flush(this global::TUnit.Mocks.Mock<global::IReadWriter> mock)
{
var s = (IReadWriter_MockSetup)setup;
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
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<string> Read(this global::TUnit.Mocks.IMockSetup<global::IReadWriter> setup)
public static global::TUnit.Mocks.MockMethodCall<string> Read(this global::TUnit.Mocks.Mock<global::IReadWriter> mock)
{
var s = (IReadWriter_MockSetup)setup;
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
var methodSetup = new global::TUnit.Mocks.Setup.MethodSetup(1, matchers, "Read");
s.Engine.AddSetup(methodSetup);
return new global::TUnit.Mocks.Setup.MethodSetupBuilder<string>(methodSetup);
return new global::TUnit.Mocks.MockMethodCall<string>(mock.Engine, 1, "Read", matchers);
}

public static IReadWriter_Write_M2_TypedSetup Write(this global::TUnit.Mocks.IMockSetup<global::IReadWriter> setup, global::TUnit.Mocks.Arguments.Arg<string> data)
public static IReadWriter_Write_M2_MockCall Write(this global::TUnit.Mocks.Mock<global::IReadWriter> mock, global::TUnit.Mocks.Arguments.Arg<string> 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<global::TUnit.Mocks.Setup.VoidMethodSetupBuilder> _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<global::TUnit.Mocks.Setup.VoidMethodSetupBuilder>(() =>
{
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;

/// <inheritdoc />
public IReadWriter_Write_M2_TypedSetup Throws<TException>() where TException : global::System.Exception, new() { _inner.Throws<TException>(); return this; }
public IReadWriter_Write_M2_MockCall Throws<TException>() where TException : global::System.Exception, new() { EnsureSetup().Throws<TException>(); return this; }
/// <inheritdoc />
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; }
/// <inheritdoc />
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; }
/// <inheritdoc />
public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action<object?[]> callback) { _inner.Callback(callback); return this; }
public IReadWriter_Write_M2_MockCall Callback(global::System.Action<object?[]> callback) { EnsureSetup().Callback(callback); return this; }
/// <inheritdoc />
public IReadWriter_Write_M2_TypedSetup Throws(global::System.Func<object?[], global::System.Exception> exceptionFactory) { _inner.Throws(exceptionFactory); return this; }
public IReadWriter_Write_M2_MockCall Throws(global::System.Func<object?[], global::System.Exception> exceptionFactory) { EnsureSetup().Throws(exceptionFactory); return this; }
/// <inheritdoc />
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; }
/// <inheritdoc />
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; }
/// <inheritdoc />
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; }
/// <inheritdoc />
public IReadWriter_Write_M2_TypedSetup Then() { _inner.Then(); return this; }
public IReadWriter_Write_M2_MockCall Then() { EnsureSetup().Then(); return this; }

/// <summary>Execute a typed callback using the actual method parameters.</summary>
public IReadWriter_Write_M2_TypedSetup Callback(global::System.Action<string> callback)
public IReadWriter_Write_M2_MockCall Callback(global::System.Action<string> callback)
{
_inner.Callback(args => callback((string)args[0]!));
EnsureSetup().Callback(args => callback((string)args[0]!));
return this;
}

/// <summary>Configure a typed computed exception using the actual method parameters.</summary>
public IReadWriter_Write_M2_TypedSetup Throws(global::System.Func<string, global::System.Exception> exceptionFactory)
public IReadWriter_Write_M2_MockCall Throws(global::System.Func<string, global::System.Exception> exceptionFactory)
{
_inner.Throws(args => exceptionFactory((string)args[0]!));
EnsureSetup().Throws(args => exceptionFactory((string)args[0]!));
return this;
}
}
}


// ===== FILE SEPARATOR =====

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
{
public sealed class IReadWriter_MockVerify : global::TUnit.Mocks.IMockVerify<global::IReadWriter>
{
internal readonly global::TUnit.Mocks.MockEngine<global::IReadWriter> Engine;

internal IReadWriter_MockVerify(global::TUnit.Mocks.MockEngine<global::IReadWriter> engine) => Engine = engine;
}

public static class IReadWriter_MockVerifyExtensions
{
public static global::TUnit.Mocks.Verification.ICallVerification Flush(this global::TUnit.Mocks.IMockVerify<global::IReadWriter> verify)
{
var v = (IReadWriter_MockVerify)verify;
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
return new global::TUnit.Mocks.Verification.CallVerificationBuilder<global::IReadWriter>(v.Engine, 0, "Flush", matchers);
}

public static global::TUnit.Mocks.Verification.ICallVerification Read(this global::TUnit.Mocks.IMockVerify<global::IReadWriter> verify)
{
var v = (IReadWriter_MockVerify)verify;
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
return new global::TUnit.Mocks.Verification.CallVerificationBuilder<global::IReadWriter>(v.Engine, 1, "Read", matchers);
}

public static global::TUnit.Mocks.Verification.ICallVerification Write(this global::TUnit.Mocks.IMockVerify<global::IReadWriter> verify, global::TUnit.Mocks.Arguments.Arg<string> data)
{
var v = (IReadWriter_MockVerify)verify;
var matchers = new global::TUnit.Mocks.Arguments.IArgumentMatcher[] { data.Matcher };
return new global::TUnit.Mocks.Verification.CallVerificationBuilder<global::IReadWriter>(v.Engine, 2, "Write", matchers);
}
// ICallVerification
/// <inheritdoc />
public void WasCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled();
/// <inheritdoc />
public void WasCalled(global::TUnit.Mocks.Times times) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times);
/// <inheritdoc />
public void WasCalled(global::TUnit.Mocks.Times times, string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(times, message);
/// <inheritdoc />
public void WasCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasCalled(message);
/// <inheritdoc />
public void WasNeverCalled() => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled();
/// <inheritdoc />
public void WasNeverCalled(string? message) => _engine.CreateVerification(_memberId, _memberName, _matchers).WasNeverCalled(message);
}
}
Loading
Loading