Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 2 additions & 2 deletions TUnit.Mocks.Benchmarks/CallbackBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class CallbackBenchmarks
public int TUnitMocks_Callback()
{
var count = 0;
var mock = Mock.Of<INotificationService>();
var mock = INotificationService.Mock();
mock.Send(TUnitArg.Any<string>(), TUnitArg.Any<string>())
.Callback(() => count++);

Expand Down Expand Up @@ -98,7 +98,7 @@ public int FakeItEasy_Callback()
public string TUnitMocks_CallbackWithArgs()
{
var lastMessage = "";
var mock = Mock.Of<ILogger>();
var mock = ILogger.Mock();
mock.Log(TUnitArg.Any<string>(), TUnitArg.Any<string>())
.Callback((string _, string msg) => lastMessage = msg);

Expand Down
4 changes: 2 additions & 2 deletions TUnit.Mocks.Benchmarks/CombinedWorkflowBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ public class CombinedWorkflowBenchmarks
public void TUnitMocks_FullWorkflow()
{
// Create
var repoMock = Mock.Of<IUserRepository>();
var loggerMock = Mock.Of<ILogger>();
var repoMock = IUserRepository.Mock();
var loggerMock = ILogger.Mock();

// Setup
repoMock.GetById(1).Returns(new User { Id = 1, Name = "Alice", Email = "alice@test.com" });
Expand Down
2 changes: 1 addition & 1 deletion TUnit.Mocks.Benchmarks/InvocationBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public class InvocationBenchmarks
public void Setup()
{
// TUnit.Mocks
_tunitMock = Mock.Of<ICalculatorService>();
_tunitMock = ICalculatorService.Mock();
_tunitMock.Add(TUnitArg.Any<int>(), TUnitArg.Any<int>()).Returns(42);
_tunitMock.Format(TUnitArg.Any<int>()).Returns("formatted");
_tunitObject = _tunitMock.Object;
Expand Down
4 changes: 2 additions & 2 deletions TUnit.Mocks.Benchmarks/MockCreationBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class MockCreationBenchmarks
[Benchmark(Description = "TUnit.Mocks")]
public object TUnitMocks_CreateMock()
{
var mock = Mock.Of<ICalculatorService>();
var mock = ICalculatorService.Mock();
return mock.Object;
}

Expand Down Expand Up @@ -58,7 +58,7 @@ public object FakeItEasy_CreateMock()
[Benchmark(Description = "TUnit.Mocks (Repository)")]
public object TUnitMocks_CreateMock_Repository()
{
var mock = Mock.Of<IUserRepository>();
var mock = IUserRepository.Mock();
return mock.Object;
}

Expand Down
4 changes: 2 additions & 2 deletions TUnit.Mocks.Benchmarks/SetupBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class SetupBenchmarks
[Benchmark(Description = "TUnit.Mocks")]
public object TUnitMocks_Setup()
{
var mock = Mock.Of<ICalculatorService>();
var mock = ICalculatorService.Mock();
mock.Add(TUnitArg.Any<int>(), TUnitArg.Any<int>()).Returns(42);
mock.Format(TUnitArg.Any<int>()).Returns("formatted");
mock.Divide(TUnitArg.Any<double>(), TUnitArg.Any<double>()).Returns(1.5);
Expand Down Expand Up @@ -76,7 +76,7 @@ public object FakeItEasy_Setup()
[Benchmark(Description = "TUnit.Mocks (Multiple)")]
public object TUnitMocks_MultipleSetups()
{
var mock = Mock.Of<IUserRepository>();
var mock = IUserRepository.Mock();
mock.GetById(1).Returns(new User { Id = 1, Name = "Alice" });
mock.GetById(2).Returns(new User { Id = 2, Name = "Bob" });
mock.GetById(3).Returns(new User { Id = 3, Name = "Charlie" });
Expand Down
6 changes: 3 additions & 3 deletions TUnit.Mocks.Benchmarks/VerificationBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class VerificationBenchmarks
[Benchmark(Description = "TUnit.Mocks")]
public void TUnitMocks_Verify()
{
var mock = Mock.Of<ICalculatorService>();
var mock = ICalculatorService.Mock();
mock.Add(TUnitArg.Any<int>(), TUnitArg.Any<int>()).Returns(42);
var calc = mock.Object;
calc.Add(1, 2);
Expand Down Expand Up @@ -86,7 +86,7 @@ public void FakeItEasy_Verify()
[Benchmark(Description = "TUnit.Mocks (Never)")]
public void TUnitMocks_VerifyNever()
{
var mock = Mock.Of<ICalculatorService>();
var mock = ICalculatorService.Mock();
mock.Format(TUnitArg.Any<int>()).WasNeverCalled();
}

Expand Down Expand Up @@ -129,7 +129,7 @@ public void FakeItEasy_VerifyNever()
[Benchmark(Description = "TUnit.Mocks (Multiple)")]
public void TUnitMocks_VerifyMultiple()
{
var mock = Mock.Of<IUserRepository>();
var mock = IUserRepository.Mock();
mock.GetById(TUnitArg.Any<int>()).Returns(new User { Id = 1, Name = "Test" });
mock.Exists(TUnitArg.Any<int>()).Returns(true);

Expand Down
53 changes: 53 additions & 0 deletions TUnit.Mocks.SourceGenerator.Tests/MockGeneratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,59 @@ public virtual void DoWork() { }
return VerifyGeneratorOutput(source);
}

[Test]
public Task Class_With_Constructor_Parameters_Extension_Discovery()
{
var source = """
using TUnit.Mocks;

public class MyService
{
public MyService() { }
public MyService(string connectionString, int timeout) { }
public MyService(string connectionString, int timeout, bool verbose) { }
public virtual string GetValue() => "real";
}

public class TestUsage
{
void M()
{
var mock = MyService.Mock();
}
}
""";

return VerifyGeneratorOutput(source);
}

[Test]
public Task Class_With_Same_Arity_Constructor_Overloads()
{
var source = """
using TUnit.Mocks;

public class MyService
{
public MyService(string name) { }
public MyService(int id) { }
public MyService(string host, int port) { }
public MyService(int timeout, bool verbose) { }
public virtual string GetValue() => "real";
}

public class TestUsage
{
void M()
{
var mock = MyService.Mock("test");
}
}
""";

return VerifyGeneratorOutput(source);
}

[Test]
public Task Static_Extension_Discovery_Without_Mock_Of()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
{
file sealed class MyServiceMockImpl : global::MyService, global::TUnit.Mocks.IRaisable, global::TUnit.Mocks.IMockObject
{
private readonly global::TUnit.Mocks.MockEngine<global::MyService> _engine;

[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
global::TUnit.Mocks.IMock? global::TUnit.Mocks.IMockObject.MockWrapper { get; set; }

internal MyServiceMockImpl(global::TUnit.Mocks.MockEngine<global::MyService> engine) : base()
{
_engine = engine;
}
internal MyServiceMockImpl(global::TUnit.Mocks.MockEngine<global::MyService> engine, string connectionString, int timeout) : base(connectionString, timeout)
{
_engine = engine;
}
internal MyServiceMockImpl(global::TUnit.Mocks.MockEngine<global::MyService> engine, string connectionString, int timeout, bool verbose) : base(connectionString, timeout, verbose)
{
_engine = engine;
}

public override string GetValue()
{
if (_engine.TryHandleCallWithReturn<string>(0, "GetValue", global::System.Array.Empty<object?>(), "", out var __result))
{
return __result;
}
return base.GetValue();
}

[global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
public void RaiseEvent(string eventName, object? args)
{
throw new global::System.InvalidOperationException($"No event named '{eventName}' exists on this mock.");
}
}

file static class MyServicePartialMockFactory
{
[global::System.Runtime.CompilerServices.ModuleInitializer]
internal static void Register()
{
global::TUnit.Mocks.MockRegistry.RegisterFactory<global::MyService>(Create);
}

private static global::TUnit.Mocks.Mock<global::MyService> Create(global::TUnit.Mocks.MockBehavior behavior, object[] constructorArgs)
{
var engine = new global::TUnit.Mocks.MockEngine<global::MyService>(behavior);
MyServiceMockImpl impl;
if (constructorArgs.Length == 0)
{
impl = new MyServiceMockImpl(engine);
}
else if (constructorArgs.Length == 2)
{
if ((constructorArgs[0] is null or string) && constructorArgs[1] is int)
{
impl = new MyServiceMockImpl(engine, (string)constructorArgs[0], (int)constructorArgs[1]);
}
else
{
throw new global::System.ArgumentException($"No matching constructor found for type 'global::MyService' with the provided argument types.");
}
}
else if (constructorArgs.Length == 3)
{
if ((constructorArgs[0] is null or string) && constructorArgs[1] is int && constructorArgs[2] is bool)
{
impl = new MyServiceMockImpl(engine, (string)constructorArgs[0], (int)constructorArgs[1], (bool)constructorArgs[2]);
}
else
{
throw new global::System.ArgumentException($"No matching constructor found for type 'global::MyService' with the provided argument types.");
}
}
else
{
throw new global::System.ArgumentException($"No matching constructor found for type 'global::MyService' with {constructorArgs.Length} argument(s).");
}
engine.Raisable = impl;
var mock = new global::TUnit.Mocks.Mock<global::MyService>(impl, engine);
return mock;
}
}
}


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

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated
{
public static class MyService_MockMemberExtensions
{
public static global::TUnit.Mocks.MockMethodCall<string> GetValue(this global::TUnit.Mocks.Mock<global::MyService> mock)
{
var matchers = global::System.Array.Empty<global::TUnit.Mocks.Arguments.IArgumentMatcher>();
return new global::TUnit.Mocks.MockMethodCall<string>(global::TUnit.Mocks.MockRegistry.GetEngine(mock), 0, "GetValue", matchers);
}
}
}


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

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks
{
public static class MyService_MockStaticExtension
{
extension(global::MyService)
{
public static global::TUnit.Mocks.Mock<global::MyService> Mock(global::TUnit.Mocks.MockBehavior behavior = global::TUnit.Mocks.MockBehavior.Loose)
{
return global::TUnit.Mocks.Mock.Of<global::MyService>(behavior);
}

public static global::TUnit.Mocks.Mock<global::MyService> Mock(string connectionString, int timeout, global::TUnit.Mocks.MockBehavior behavior = global::TUnit.Mocks.MockBehavior.Loose)
{
return global::TUnit.Mocks.Mock.Of<global::MyService>(behavior, connectionString, timeout);
}

public static global::TUnit.Mocks.Mock<global::MyService> Mock(string connectionString, int timeout, bool verbose, global::TUnit.Mocks.MockBehavior behavior = global::TUnit.Mocks.MockBehavior.Loose)
{
return global::TUnit.Mocks.Mock.Of<global::MyService>(behavior, connectionString, timeout, verbose);
}
}
}
}


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

// <auto-generated/>
#nullable enable

namespace TUnit.Mocks.Generated;
Loading
Loading