diff --git a/Src/AutoFixture.NUnit3.UnitTest/AutoFixture.NUnit3.UnitTest.csproj b/Src/AutoFixture.NUnit3.UnitTest/AutoFixture.NUnit3.UnitTest.csproj
index 603f933d3..55698216a 100644
--- a/Src/AutoFixture.NUnit3.UnitTest/AutoFixture.NUnit3.UnitTest.csproj
+++ b/Src/AutoFixture.NUnit3.UnitTest/AutoFixture.NUnit3.UnitTest.csproj
@@ -62,8 +62,12 @@
+
+
+
+
diff --git a/Src/AutoFixture.NUnit3.UnitTest/FixedNameTestMethodBuilderTest.cs b/Src/AutoFixture.NUnit3.UnitTest/FixedNameTestMethodBuilderTest.cs
new file mode 100644
index 000000000..00c6d4287
--- /dev/null
+++ b/Src/AutoFixture.NUnit3.UnitTest/FixedNameTestMethodBuilderTest.cs
@@ -0,0 +1,25 @@
+using NUnit.Framework;
+using NUnit.Framework.Internal;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Ploeh.AutoFixture.NUnit3.UnitTest
+{
+ public class FixedNameTestMethodBuilderTest
+ {
+ [Test]
+ public void FixedNameTestMethodBuilderIsResilientToFactoryException()
+ {
+ // Fixture setup
+ var method = new MethodWrapper(typeof(TestNameStrategiesFixture), nameof(TestNameStrategiesFixture.FixedNameDecoratedMethod));
+ var sut = new FixedNameTestMethodBuilder();
+ // Exercise system
+ var testMethod = sut.Build(method, null, () => throw new Exception(), 0);
+ // Verify outcome
+ Assert.That(testMethod.Name, Is.EqualTo(nameof(TestNameStrategiesFixture.FixedNameDecoratedMethod)));
+ // Teardown
+ }
+ }
+}
diff --git a/Src/AutoFixture.NUnit3.UnitTest/Scenario.cs b/Src/AutoFixture.NUnit3.UnitTest/Scenario.cs
index 4c93f1454..c45127dde 100644
--- a/Src/AutoFixture.NUnit3.UnitTest/Scenario.cs
+++ b/Src/AutoFixture.NUnit3.UnitTest/Scenario.cs
@@ -378,7 +378,7 @@ public void InlineAutoDataCanBeUsedWithFrozen(int p1, int p2, [Frozen]string p3,
[Theory, AutoData]
public void NoAutoPropertiesAttributeLeavesPropertiesUnset(
- [NoAutoProperties]PropertyHolder
+
@@ -84,6 +85,8 @@
+
+
diff --git a/Src/AutoFixture.NUnit3/FixedNameTestMethodBuilder.cs b/Src/AutoFixture.NUnit3/FixedNameTestMethodBuilder.cs
new file mode 100644
index 000000000..cc003ff11
--- /dev/null
+++ b/Src/AutoFixture.NUnit3/FixedNameTestMethodBuilder.cs
@@ -0,0 +1,105 @@
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework.Interfaces;
+using NUnit.Framework.Internal;
+using System.Globalization;
+using NUnit.Framework.Internal.Builders;
+using System.Diagnostics.CodeAnalysis;
+
+namespace Ploeh.AutoFixture.NUnit3
+{
+ ///
+ /// Builder that generates with fixed names.
+ /// This is needed for some test runners such as the Nunit test adaptor for Visual Studio.
+ ///
+ ///
+ public class FixedNameTestMethodBuilder : ITestMethodBuilder
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public FixedNameTestMethodBuilder() { }
+
+ ///
+ public virtual TestMethod Build(IMethodInfo method, Test suite, Func argFactory, int autoDataStartIndex)
+ {
+ if (method == null)
+ {
+ throw new ArgumentNullException(nameof(method));
+ }
+
+ if (argFactory == null)
+ {
+ throw new ArgumentNullException(nameof(argFactory));
+ }
+
+ return new NUnitTestCaseBuilder().BuildTestMethod(method, suite, GetParametersForMethod(method, argFactory, autoDataStartIndex));
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method is always expected to return an instance of the TestCaseParameters class.")]
+ private static TestCaseParameters GetParametersForMethod(IMethodInfo method, Func argFactory, int autoDataStartIndex)
+ {
+ try
+ {
+ var parameterValues = argFactory();
+ return GetParametersForMethod(method, parameterValues.ToArray(), autoDataStartIndex);
+ }
+ catch (Exception ex)
+ {
+ return new TestCaseParameters(ex);
+ }
+ }
+
+ private static TestCaseParameters GetParametersForMethod(IMethodInfo method, object[] args, int autoDataStartIndex)
+ {
+ var result = new TestCaseParameters(args);
+ var methodParameters = method.GetParameters();
+
+ EnsureOriginalArgumentsArrayIsNotShared(result);
+
+ for (int i = autoDataStartIndex; i < result.OriginalArguments.Length; i++)
+ {
+ result.OriginalArguments[i] = new TypeNameRenderer(methodParameters[i].ParameterType);
+ }
+
+ return result;
+ }
+
+ ///
+ /// In NUnit 3.5+ the Arguments and OriginalArguments properties are containing two different instances,
+ /// not in earlier versions.
+ /// Unfortunately OriginalArguments has a private setter and there is not way to change the instance other
+ /// than by using reflection...
+ /// When running in NUnit3.5+ the method is supposed to do nothing.
+ ///
+ private static void EnsureOriginalArgumentsArrayIsNotShared(TestCaseParameters parameters)
+ {
+ if (ReferenceEquals(parameters.Arguments, parameters.OriginalArguments))
+ {
+ var clonedArguments = new object[parameters.OriginalArguments.Length];
+ Array.Copy(parameters.OriginalArguments, clonedArguments, parameters.OriginalArguments.Length);
+
+ var property = typeof(TestParameters).GetProperty(nameof(TestCaseParameters.OriginalArguments));
+ property.SetValue(parameters, clonedArguments, null);
+ }
+ }
+
+ private class TypeNameRenderer
+ {
+ public Type Type { get; }
+
+ public TypeNameRenderer(Type type)
+ {
+ this.Type = type ?? throw new ArgumentNullException(nameof(type));
+ }
+
+ public override string ToString()
+ {
+ return "auto<" + Type.Name + ">";
+ }
+ }
+ }
+}
diff --git a/Src/AutoFixture.NUnit3/ITestMethodBuilder.cs b/Src/AutoFixture.NUnit3/ITestMethodBuilder.cs
new file mode 100644
index 000000000..643efdf1e
--- /dev/null
+++ b/Src/AutoFixture.NUnit3/ITestMethodBuilder.cs
@@ -0,0 +1,24 @@
+using NUnit.Framework.Interfaces;
+using NUnit.Framework.Internal;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+
+namespace Ploeh.AutoFixture.NUnit3
+{
+ ///
+ /// Utility used to create a instance.
+ ///
+ public interface ITestMethodBuilder
+ {
+ ///
+ /// Builds a from a method and the argument values.
+ ///
+ /// The MethodInfo for which tests are to be constructed.
+ /// The suite to which the tests will be added.
+ /// The argument values generated for the test case.
+ /// Index at which the autodata values have been generated.
+ TestMethod Build(IMethodInfo method, Test suite, Func argFactory, int autoDataStartIndex);
+ }
+}
diff --git a/Src/AutoFixture.NUnit3/InlineAutoDataAttribute.cs b/Src/AutoFixture.NUnit3/InlineAutoDataAttribute.cs
index acadf34a8..82608be2a 100644
--- a/Src/AutoFixture.NUnit3/InlineAutoDataAttribute.cs
+++ b/Src/AutoFixture.NUnit3/InlineAutoDataAttribute.cs
@@ -20,6 +20,16 @@ public class InlineAutoDataAttribute : Attribute, ITestBuilder
private readonly object[] _existingParameterValues;
private readonly IFixture _fixture;
+ private ITestMethodBuilder _testMethodBuilder = new VolatileNameTestMethodBuilder();
+ ///
+ /// Gets or sets the current strategy.
+ ///
+ public ITestMethodBuilder TestMethodBuilder
+ {
+ get => _testMethodBuilder;
+ set => _testMethodBuilder = value ?? throw new ArgumentNullException(nameof(value));
+ }
+
///
/// Construct a
/// with parameter values for test method
@@ -66,28 +76,11 @@ public IEnumerable Arguments
/// One or more TestMethods
public IEnumerable BuildFrom(IMethodInfo method, Test suite)
{
- var test = new NUnitTestCaseBuilder().BuildTestMethod(method, suite, this.GetParametersForMethod(method));
+ var test = TestMethodBuilder.Build(method, suite, () => GetParameterValues(method.GetParameters()).ToArray(), _existingParameterValues.Count());
yield return test;
}
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method is always expected to return an instance of the TestCaseParameters class.")]
- private TestCaseParameters GetParametersForMethod(IMethodInfo method)
- {
- try
- {
- var parameters = method.GetParameters();
-
- var parameterValues = this.GetParameterValues(parameters);
-
- return new TestCaseParameters(parameterValues.ToArray());
- }
- catch (Exception ex)
- {
- return new TestCaseParameters(ex);
- }
- }
-
///
/// Get values for a collection of
///
diff --git a/Src/AutoFixture.NUnit3/VolatileNameTestMethodBuilder.cs b/Src/AutoFixture.NUnit3/VolatileNameTestMethodBuilder.cs
new file mode 100644
index 000000000..d76cc55ed
--- /dev/null
+++ b/Src/AutoFixture.NUnit3/VolatileNameTestMethodBuilder.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework.Interfaces;
+using NUnit.Framework.Internal;
+using System.Diagnostics.CodeAnalysis;
+using NUnit.Framework.Internal.Builders;
+
+namespace Ploeh.AutoFixture.NUnit3
+{
+ ///
+ /// Utility used to create a instance.
+ ///
+ ///
+ public class VolatileNameTestMethodBuilder : ITestMethodBuilder
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public VolatileNameTestMethodBuilder() { }
+
+ ///
+ public TestMethod Build(IMethodInfo method, Test suite, Func argFactory, int autoDataStartIndex)
+ {
+ if (method == null)
+ {
+ throw new ArgumentNullException(nameof(method));
+ }
+
+ if (argFactory == null)
+ {
+ throw new ArgumentNullException(nameof(argFactory));
+ }
+
+ return new NUnitTestCaseBuilder().BuildTestMethod(method, suite, GetParametersForMethod(argFactory));
+ }
+
+ [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method is always expected to return an instance of the TestCaseParameters class.")]
+ private static TestCaseParameters GetParametersForMethod(Func argFactory)
+ {
+ try
+ {
+ var parameterValues = argFactory();
+ return GetParametersForMethod(parameterValues.ToArray());
+ }
+ catch (Exception ex)
+ {
+ return new TestCaseParameters(ex);
+ }
+ }
+
+ private static TestCaseParameters GetParametersForMethod(object[] args)
+ {
+ return new TestCaseParameters(args);
+ }
+ }
+}