C#:no se puede pasar el parámetro decimal en DataTestMethod

C#:no se puede pasar el parámetro decimal en DataTestMethod

Tengo una prueba unitaria parametrizada con parámetros decimales.

[DataRow(0.0, 1.0, 1.0)]
[DataRow(1.0, 1.0, 2.0)]
[DataRow(2.0, 2.0, 4.0)]
[DataTestMethod]
public void TestAdd(decimal a, decimal b, decimal expectedAnswer)
{
	var actualAnswer = a.Add(b);

	Assert.AreEqual(expectedAnswer, actualAnswer);
}
Code language: C# (cs)

Cuando ejecuto la prueba, obtengo la siguiente excepción:

Solución

Cambie los parámetros a dobles y conviértalos a decimales dentro del método de prueba.

[DataRow(0.0, 1.0, 1.0)]
[DataRow(1.0, 1.0, 2.0)]
[DataRow(2.0, 2.0, 4.0)]
[DataTestMethod]
public void TestAdd(double a, double b, double expectedAnswer)
{
	decimal A = Convert.ToDecimal(a);
	decimal B = Convert.ToDecimal(b);
	decimal expected = Convert.ToDecimal(expectedAnswer);

	var actualAnswer = A.Add(B);

	Assert.AreEqual(expected, actualAnswer);
}
Code language: C# (cs)

¿Por qué lanza una excepción?

Tienes que pasar dobles, no decimales. DataRow() es un atributo y, por lo tanto, tiene restricciones de parámetros. Obtendrá un error de tiempo de compilación si intenta especificar un tipo decimal, es decir, [DataRow(0.0m, 1.0m, 1.0m)].

El marco de prueba ejecuta su prueba de unidad usando la reflexión. Cuando se invoca un método usando la reflexión, tiene que intentar hacer coincidir los parámetros que pasó con los parámetros del método.

Debido a que tiene que pasar dobles y el método tiene un parámetro decimal, tiene que convertir estos dobles en decimales. Aparentemente, cuando invoca un método usando la reflexión, no puede manejar esta conversión.

Puedo recrear esta excepción usando la reflexión para llamar a un método, pasando un doble donde espera un decimal:

double dbl = 1.0;
A A = new A();
A.GetType().GetMethod("DoNothing").Invoke(A, new object[] { dbl });

public class A
{
	public void DoNothing(decimal a) 
	{ 
	
	}
}
Code language: C# (cs)

Según el seguimiento de la pila, la excepción proviene de RuntimeType.TryChangeType(…). Por alguna razón, no puede manejar esta conversión.


No