C# – Can’t pass decimal parameter in DataTestMethod

I have a parameterized unit test with decimal parameters.

[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);
}

When I run the test, I get the following exception:

System.ArgumentException: Object of type ‘System.Double’ cannot be converted to type ‘System.Decimal’.

Solution

Change the parameters to doubles and convert them to decimals inside the test method.

[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);
}

Why is it throwing an exception?

You have to pass doubles, not decimals. DataRow() is an attribute, and therefore has parameter constraints. You’ll get a compile-time error if you try to specify a decimal type, i.e. [DataRow(0.0m, 1.0m, 1.0m)].

The test framework runs your unit test using reflection. When a method is invoked using reflection, it has to try to match up the parameters you passed in with the method’s parameters.

Because you have to pass doubles, and the method has decimal parameter, it has to convert these doubles into decimals. Apparently when you are invoking a method using reflection, it can’t handle this conversion.

I can recreate this exception by using reflection to call a method, passing in a double where it expects a 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) 
	{ 
	
	}
}

According to the stack trace, the exception is coming from RuntimeType.TryChangeType(…). For some reason it can’t handle this conversion.

Leave a Comment