Test paramétrico con métodos genéricos.
-
03-07-2019 - |
Pregunta
En NUnit 2.5 puedes hacer esto:
[TestCase(1,5,7)]
public void TestRowTest(int i, int j, int k)
{
Assert.AreEqual(13, i+j+k);
}
Puedes hacer una prueba paramétrica.
¿Pero me pregunto si puede hacer esto o no, prueba paramétrica con método de prueba genérico? Es decir:
[TestCase <int>("Message")]
public void TestRowTestGeneric<T>(string msg)
{
Assert.AreEqual(5, ConvertStrToGenericParameter<T>(msg));
}
O algo similar.
Solución
Aquí está la cita de la nota de publicación de NUnit 2.5 texto del enlace
Los métodos de prueba parametrizados pueden ser genérico. NUnit deducirá la correcta Implementación para utilizar basado en el Tipos de parámetros proporcionados. Métodos de prueba genéricos son compatibles en clases tanto genéricas como no genéricas.
De acuerdo con esto, es posible tener un método de prueba genérico en una clase no genérica. ¿Cómo?
No entiendo muy bien el comentario de Jeff. En .net genéricos es tanto el tiempo de compilación como el de ejecución. Podemos usar la reflexión para averiguar el atributo de caso de prueba asociado con un método, averiguar el parámetro genérico y nuevamente usar la reflexión para llamar al método genérico. Funcionará, ¿no?
Actualización: OK, ahora sé cómo y espero que no sea demasiado tarde. Necesita que el tipo genérico esté en la lista de parámetros. Por ejemplo:
[TestCase((int)5, "5")]
[TestCase((double)2.3, "2.3")]
public void TestRowTestGeneric<T>(T value, string msg)
{
Assert.AreEqual(value, ConvertStrToGenericParameter<T>(msg));
}
Otros consejos
Puedes hacer GenericTestCaseAttribute personalizado
[Test]
[GenericTestCase(typeof(MyClass) ,"Some response", TestName = "Test1")]
[GenericTestCase(typeof(MyClass1) ,"Some response", TestName = "Test2")]
public void MapWithInitTest<T>(string expectedResponse)
{
// Arrange
// Act
var response = MyClassUnderTest.MyMethod<T>();
// Assert
Assert.AreEqual(expectedResponse, response);
}
Aquí está la implementación de GenericTestCaseAttribute
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
public class GenericTestCaseAttribute : TestCaseAttribute, ITestBuilder
{
private readonly Type _type;
public GenericTestCaseAttribute(Type type, params object[] arguments) : base(arguments)
{
_type = type;
}
IEnumerable<TestMethod> ITestBuilder.BuildFrom(IMethodInfo method, Test suite)
{
if (method.IsGenericMethodDefinition && _type != null)
{
var gm = method.MakeGenericMethod(_type);
return BuildFrom(gm, suite);
}
return BuildFrom(method, suite);
}
}
Crea un método privado y llama a eso:
[Test]
public void TypeATest()
{
MyTest<TypeA>();
}
[Test]
public void TypeBTest()
{
MyTest<TypeB>();
}
private void MyTest<T>()
{
// do test.
}