C# Unit Test DynamicData using MSTest

34 views Asked by At

I am performing some unit test using MSTest and I learned that I can use the [DynamicData] attribute to input different cases for testing.

I have returned object[] from static method, inside the static method performed object assigning to List and return that list object. In this case i am getting System.Reflection.TargetParameterCountException: Parameter count mismatch while run the test cases. exception.

For reference i have added sample code .

Test method:

[TestMethod]
[DynamicData(nameof(GetTestData), DynamicDataSourceType.Method)]
public void TestMethod3(data obj)
{
    
    var _controller = new SampleController();
    var result = _controller.GetAlertTypes(obj.number, obj.size);
    Assert.IsNotNull(result);
}
    
private static IEnumerable<data[]> GetTestData()
{
    List<data> result = new List<data>();
                
    data data1 = new data();
    data1.number = 1;
    data1.size = 1;
    result.Add(data1);
    data data2 = new data();
    data2.number = 10;
    data2.size = 2;
    result.Add(data2);
    yield return result.ToArray();
}
1

There are 1 answers

4
CKII On

You're returning IEnumerable<Data[]> as the return type from GetTestData. But you accept data obj in your test.

Dynamic data must return an enumerable, since each item is a different test case, but you're returning another enumerable inside, instead of a single data.

You're method should look more like this --

private static IEnumerable<data> GetTestData()
{            
    data data1 = new data();
    data1.number = 1;
    data1.size = 1;
    yield return data1; // Data for case #1

    data data2 = new data();
    data2.number = 10;
    data2.size = 2;
    yield return data2; // Data for case #2
}

EDIT:

Looking again at the documentation your comment is correct. You need to return an enumerable of arrays from the dynamic data method. However, the inner array allows for multiple parameters in the test method. Each separate array is considered a new test case.

You've placed both instances of data in the same array, so it's like the test expects two parameters of data as its input.

The correct method should have been:

private static IEnumerable<object[]> GetTestData()
{            
    data data1 = new data();
    data1.number = 1;
    data1.size = 1;
    yield return new object[] { data1 }; // Data for case #1

    data data2 = new data();
    data2.number = 10;
    data2.size = 2;
    yield return new object[] { data2 }; // Data for case #2
}

But then again, your test only uses the data class as a package for the parameters. You're not passing the data instance your actual code. So you can rewrite the test to look like this:

[TestMethod]
[DynamicData(nameof(GetTestData), DynamicDataSourceType.Method)]
public void TestMethod3(int number, int size)
{
    
    var _controller = new SampleController();
    var result = _controller.GetAlertTypes(number, size);
    Assert.IsNotNull(result);
}

private static IEnumerable<object[]> GetTestData()
{            
    return new[] 
    {
        new object[] { 1, 1 }; // Test case #1
        new object[] { 10, 2 }; // Test case #2
    };
}

And if the data doesn't require runtime initialization, you can also use DataRow:

[TestMethod]
[DataRow(1, 1)]
[DataRow(10, 2)]
public void TestMethod3(int number, int size)
{
    
    var _controller = new SampleController();
    var result = _controller.GetAlertTypes(number, size);
    Assert.IsNotNull(result);
}

Hope this helps