Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using decimal values in DataRowAttribute

I've got a c# assembly for Tests to run in Visual Studio 2017 using MSTest.TestAdaptor 1.1.17. I want to use a DataTestMethod to run a test with several datasets. My Problem is, I want to use decimal values in my DataRows but can't:

[DataTestMethod]
[DataRow(1m, 2m, 3m)]
[DataRow(1, 2, 3)]
[DataRow(1.0, 2.0, 3.0)]
public void CheckIt(decimal num1, decimal num2, decimal expected)
{
}

When I try to use [DataRow(100m, 7m, 7m)] it won't even compile the source: error CS0182: An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type..

When I use [DataRow(100, 7, 7)] the test will fail since my test expects decimal but gets int32 as value.

When I use [DataRow(100.0, 7.0, 7.0)] the test will fail since my test expects decimal but gets double as value.

Why can't I use decimal numbers in a DataRow?

like image 639
Sam Avatar asked May 04 '17 15:05

Sam


2 Answers

It's because decimal is not a primitive type

The solution is to use strings and then convert your parameters in your test.

like image 172
pln Avatar answered Oct 20 '22 17:10

pln


This is limitation of C# not just of the testing framework. You can also use DynamicData attribute that will query a static property or method for data. You make it output array of array of objects. That is one item per "datarow", and in that one item per parameter you wish to provide. You are also not limited to pass primitive types, you can pass arbitrary objects to your parameters. Here is a great example of that https://stackoverflow.com/a/47791172.

Here is an example of passing decimals:

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        // static!
        public static IEnumerable<object[]> TestMethod1Data =>
            // one item per data row
            new[] {
                // one item per parameter, you need to specify the object type
                new object[] { 1m, 2m, 3m },
                new object[] { 13.5m, 178.8m, 192.3m }
            };

        [TestMethod]
        // you can also use a method, but it defaults to property
        [DynamicData(nameof(TestMethod1Data))]
        public void TestMethod1(decimal l, decimal r, decimal expected)
        {
            Assert.AreEqual(expected, l  +  r);
        }
    }
}
like image 5
nohwnd Avatar answered Oct 20 '22 16:10

nohwnd