Skip to content

Commit

Permalink
fix: Generator with nullable or optional parameters (#273)
Browse files Browse the repository at this point in the history
* Test generator

* #WIP

* NuGet config

* Proof of working

* Fix build error

* Auto stash before merge of "BMichaelis/TestGenerator" and "BenjaminMichaelis/BMichaelis/TestGenerator"

* More test, working generator

* Removing caching of symbol

* Add tests, adjust docs

* More cleanup

* revert global.json update

* Revert "NuGet config". Will be done in #270

This reverts commit b990391.

---------

Co-authored-by: Kevin Bost <kitokeboo@gmail.com>
  • Loading branch information
BenjaminMichaelis and Keboo authored Jan 29, 2024
1 parent 580a55d commit f1d4414
Show file tree
Hide file tree
Showing 12 changed files with 675 additions and 221 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Moq.AutoMock.Generator.Example.MSTest;

[TestClass]
[ConstructorTests(typeof(ControllerWithSomeNullableParameters), Behavior = TestGenerationBehavior.IgnoreNullableParameters)]
public partial class ControllerNullableParametersTests
{
partial void ControllerWithSomeNullableParametersConstructor_WithNullstring_ThrowsArgumentNullExceptionSetup(AutoMocker mocker)
{
mocker.Use<string>("");
mocker.Use<int?>(42);
mocker.Use<int>(24);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Moq.AutoMock.Generator.Example.NUnit;

[ConstructorTests(typeof(ControllerWithSomeNullableParameters), Behavior = TestGenerationBehavior.IgnoreNullableParameters)]
public partial class ControllerNullableParametersTests
{
partial void AutoMockerTestSetup(Moq.AutoMock.AutoMocker mocker, string testName)
{
mocker.Use<string>("");
mocker.Use<int?>(42);
mocker.Use<int>(24);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
namespace Moq.AutoMock.Generator.Example.xUnit;

[ConstructorTests(typeof(ControllerWithSomeNullableParameters), Behavior = TestGenerationBehavior.IgnoreNullableParameters)]
public partial class ControllerNullableParametersTests
{
partial void AutoMockerTestSetup(Moq.AutoMock.AutoMocker mocker, string testName)
{
mocker.Use<string>("");
mocker.Use<int?>(42);
mocker.Use<int>(24);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Moq.AutoMock.Generator.Example;

public class ControllerWithSomeNullableParameters
{
public ControllerWithSomeNullableParameters(
string name, // Test generated
int years, // No test generated
string? nullableName, // No test generated
string? testName = null, // No test generated
string foo = null!, // No test generated
int? age = null) // No test generated
{
ArgumentNullException.ThrowIfNull(name);
}
}
18 changes: 16 additions & 2 deletions Moq.AutoMock/ConstructorTestsAttribute.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
namespace Moq.AutoMock;

/// <summary>
/// An attribute used by Moq.AutoMock.TestGenerator to generate unit tests for null constructor arguments.
/// </summary>
Expand All @@ -11,16 +10,31 @@ public class ConstructorTestsAttribute : Attribute
/// </summary>
public Type? TargetType { get; set; }
/// <summary>
/// Controls whether to generate tests for nullable reference types.
/// </summary>
public TestGenerationBehavior Behavior { get; set; }
/// <summary>
/// Create a new instance of the ConstructorTestsAttribute
/// </summary>
public ConstructorTestsAttribute()
{ }
/// <summary>
/// Create a new instance of the ConstructorTestsAttribute specifying the targetType
/// </summary>
/// <param name="targetType"></param>
/// <param name="targetType">The name for which the generator should generate tests for.</param>
public ConstructorTestsAttribute(Type targetType)
{
TargetType = targetType;
}

/// <summary>
/// Create a new instance of the ConstructorTestsAttribute specifying the targetType
/// </summary>
/// <param name="targetType">The name for which the generator should generate tests for.</param>
/// <param name="behavior">Sets the behavior for the test generator to operate with.</param>
public ConstructorTestsAttribute(Type targetType, TestGenerationBehavior behavior)
{
TargetType = targetType;
Behavior = behavior;
}
}
22 changes: 22 additions & 0 deletions Moq.AutoMock/TestGenerationBehavior.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
namespace Moq.AutoMock;

/// <summary>
/// Control the behavior of the test generator, such as whether to skip nullable parameters.
/// </summary>
public enum TestGenerationBehavior
{
/// <summary>
/// The default behavior, which is to generate tests for all parameters.
/// </summary>
Default,

/// <summary>
/// Skip generating tests for parameters that meet one of the following criteria:
/// <list type="bullet">
/// <item><description>Nullable reference types are enabled and the parameter type is a nullable reference type.</description></item>
/// <item><description>The parameter is a nullable value type.</description></item>
/// <item><description>The parameter has a default value of null.</description></item>
/// </list>
/// </summary>
IgnoreNullableParameters
}
Loading

0 comments on commit f1d4414

Please sign in to comment.