métodos de prueba NUnit realidad puede ser genérico, siempre que los argumentos de tipo genérico se pueden deducir de los parámetros:
[TestCase(42)]
[TestCase("string")]
[TestCase(double.Epsilon)]
public void GenericTest<T>(T instance)
{
Console.WriteLine(instance);
}
Si los argumentos genéricos no se pueden deducir, el corredor de prueba se no tienen ni idea de cómo resolver los argumentos de tipo:
[TestCase(42)]
[TestCase("string")]
[TestCase(double.Epsilon)]
public void GenericTest<T>(object instance)
{
Console.WriteLine(instance);
}
Pero en este caso se puede aplicar un atributo personalizado:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class TestCaseGenericAttribute : TestCaseAttribute, ITestBuilder
{
public TestCaseGenericAttribute(params object[] arguments)
: base(arguments)
{
}
public Type[] TypeArguments { get; set; }
IEnumerable<TestMethod> ITestBuilder.BuildFrom(IMethodInfo method, Test suite)
{
if (!method.IsGenericMethodDefinition)
return base.BuildFrom(method, suite);
if (TypeArguments == null || TypeArguments.Length != method.GetGenericArguments().Length)
{
var parms = new TestCaseParameters { RunState = RunState.NotRunnable };
parms.Properties.Set("_SKIPREASON", $"{nameof(TypeArguments)} should have {method.GetGenericArguments().Length} elements");
return new[] { new NUnitTestCaseBuilder().BuildTestMethod(method, suite, parms) };
}
var genMethod = method.MakeGenericMethod(TypeArguments);
return base.BuildFrom(genMethod, suite);
}
}
Uso:
[TestCaseGeneric("Some response", TypeArguments = new[] { typeof(IMyInterface), typeof(MyConcreteClass) }]
public void MyMethod_GenericCall_MakesGenericCall<T1, T2>(string expectedResponse)
{
// whatever
}
Y una personalización similar para TestCaseSourceAttribute
:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class TestCaseSourceGenericAttribute : TestCaseSourceAttribute, ITestBuilder
{
public TestCaseSourceGenericAttribute(string sourceName)
: base(sourceName)
{
}
public Type[] TypeArguments { get; set; }
IEnumerable<TestMethod> ITestBuilder.BuildFrom(IMethodInfo method, Test suite)
{
if (!method.IsGenericMethodDefinition)
return base.BuildFrom(method, suite);
if (TypeArguments == null || TypeArguments.Length != method.GetGenericArguments().Length)
{
var parms = new TestCaseParameters { RunState = RunState.NotRunnable };
parms.Properties.Set("_SKIPREASON", $"{nameof(TypeArguments)} should have {method.GetGenericArguments().Length} elements");
return new[] { new NUnitTestCaseBuilder().BuildTestMethod(method, suite, parms) };
}
var genMethod = method.MakeGenericMethod(TypeArguments);
return base.BuildFrom(genMethod, suite);
}
}
Uso:
[TestCaseSourceGeneric(nameof(mySource)), TypeArguments = new[] { typeof(IMyInterface), typeof(MyConcreteClass) }]
¿Podría ser más específico sobre lo que quiere probar? En el ejemplo anterior, parece que está escribiendo pruebas de unidades para la infraestructura .NET en lugar de su código. –
Disculpa, estaba intentando que el ejemplo fuera lo más simple posible y es posible que haya ido demasiado lejos. Estoy escribiendo pruebas para probar que ciertas clases se han registrado contra ciertas interfaces en un contenedor IoC. Entiendo que esto está superando los límites de lo que debería probarse desde un punto de vista lógico. Sin embargo, hay muchas otras instancias en las que me gustaría probar el paso de diferentes tipos a un método genérico. –
NUnit TestCase puede, por supuesto, abreviarse como NUTCase. –