diff --git a/Source/Mockolate.SourceGenerators/Sources/Sources.MockClass.cs b/Source/Mockolate.SourceGenerators/Sources/Sources.MockClass.cs index f9e3058d..0648158a 100644 --- a/Source/Mockolate.SourceGenerators/Sources/Sources.MockClass.cs +++ b/Source/Mockolate.SourceGenerators/Sources/Sources.MockClass.cs @@ -15,6 +15,8 @@ internal static partial class Sources public static string MockClass(string name, Class @class, bool hasOverloadResolutionPriority = false) { EquatableArray? constructors = (@class as MockClass)?.Constructors; + bool hasParameterizedConstructor = !@class.IsInterface && + constructors?.Any(m => m.Parameters.Count > 0) == true; string escapedClassName = @class.ClassFullName.EscapeForXmlDoc(); bool hasEvents = @class.AllEvents().Any(x => !x.IsStatic); bool hasStaticEvents = @class.IsInterface && @@ -162,7 +164,7 @@ public static string MockClass(string name, Class @class, bool hasOverloadResolu sb.Append("\t\t\t=> CreateMock(mockBehavior, setup, (object?[]?)null);").AppendLine(); sb.AppendLine(); - if (!@class.IsInterface) + if (hasParameterizedConstructor) { sb.AppendXmlSummary( $"Creates a new mock of using the given to invoke the base-class constructor."); @@ -206,7 +208,7 @@ public static string MockClass(string name, Class @class, bool hasOverloadResolu sb.AppendXmlParam("setup", "Callback that receives the mock's setup surface and registers initial setups before the mock is returned, or to skip."); sb.AppendXmlParam("constructorParameters", "Values forwarded to a matching base-class constructor, or to use the parameterless constructor."); sb.AppendXmlReturns(createMockReturns); - sb.Append("\t\t").Append(@class.IsInterface ? "private" : "public").Append(" static ") + sb.Append("\t\t").Append(hasParameterizedConstructor ? "public" : "private").Append(" static ") .Append(@class.ClassFullName) .Append(" CreateMock(global::Mockolate.MockBehavior? mockBehavior, global::System.Action<") .Append(setupType).Append(">? setup, object?[]? constructorParameters)").AppendLine(); diff --git a/Tests/Mockolate.SourceGenerators.Tests/MockTests.cs b/Tests/Mockolate.SourceGenerators.Tests/MockTests.cs index c5ccf329..38f90163 100644 --- a/Tests/Mockolate.SourceGenerators.Tests/MockTests.cs +++ b/Tests/Mockolate.SourceGenerators.Tests/MockTests.cs @@ -241,6 +241,64 @@ public MyBaseClass(global::Mockolate.MockRegistry mockRegistry, int value, bool """).IgnoringNewlineStyle(); } + [Fact] + public async Task ForTypesWithOnlyParameterlessConstructor_ShouldOmitConstructorParametersOverloads() + { + GeneratorResult result = Generator + .Run(""" + using Mockolate; + + namespace MyCode; + + public class Program + { + public static void Main(string[] args) + { + _ = MyBaseClass.CreateMock(); + } + } + + public class MyBaseClass + { + public MyBaseClass() { } + } + """); + + await That(result.Sources).ContainsKey("Mock.MyBaseClass.g.cs").WhoseValue + .DoesNotContain("CreateMock(object?[] constructorParameters)").And + .DoesNotContain("CreateMock(global::Mockolate.MockBehavior mockBehavior, object?[] constructorParameters)").And + .DoesNotContain("object?[] constructorParameters)").And + .Contains("private static global::MyCode.MyBaseClass CreateMock(global::Mockolate.MockBehavior? mockBehavior, global::System.Action? setup, object?[]? constructorParameters)"); + } + + [Fact] + public async Task ForTypesWithoutExplicitConstructor_ShouldOmitConstructorParametersOverloads() + { + GeneratorResult result = Generator + .Run(""" + using Mockolate; + + namespace MyCode; + + public class Program + { + public static void Main(string[] args) + { + _ = MyBaseClass.CreateMock(); + } + } + + public class MyBaseClass + { + } + """); + + await That(result.Sources).ContainsKey("Mock.MyBaseClass.g.cs").WhoseValue + .DoesNotContain("CreateMock(object?[] constructorParameters)").And + .DoesNotContain("object?[] constructorParameters)").And + .Contains("private static global::MyCode.MyBaseClass CreateMock(global::Mockolate.MockBehavior? mockBehavior, global::System.Action? setup, object?[]? constructorParameters)"); + } + [Fact] public async Task ForTypesWithoutPublicOrProtectedConstructor_ShouldOnlyGenerateMockThatThrowsException() {