6

I am performing some unit test using MSTest and I learned that I can use the [DynamicData] attribute to input different cases for testing, but I can't use the attribute property: DynamicDataDisplayName to set a name for the different cases.

My test code is:

    [TestMethod]
    [DynamicData(nameof(TestInputs_BeReady), DynamicDataSourceType.Method,
        DynamicDataDisplayName = nameof(GetTestDisplayNames),
        DynamicDataDisplayNameDeclaringType = typeof(List<string>))]
    public void Should_BeReady(object expValue, object[] inputs)
    {
        // Arrange

        // Act
        ui.InputID = (string)inputs[0];
        ui.InputName = (string)inputs[1];
        ui.InputList = (List<string>)inputs[2];

        // Assert
        Assert.AreEqual(expValue, onReadyStateChangeArgs.Ready);
    }

    public static IEnumerable<object[]> TestInputs_BeReady()
    {
        return new[]
        {
            new object[] { true, new object[] { "UTSZ0", "Unit Test Size List" , new List<string> { "entry_01", "entry_02" } } },
            new object[] { false, new object[] { "STEST", "Unit Test Size List" , new List<string> { "entry_01", "entry_02" } } },
            new object[] { false, new object[] { "", "Unit Test Size List" , new List<string> { "entry_01", "entry_02" } } },
            new object[] { false, new object[] { "UTSZ0", "" , new List<string> { "entry_01", "entry_02" } } },
            new object[] { false, new object[] { "UTSZ0", "Unit Test Size List", new List<string>() } },
            new object[] { false, new object[] { "UTSZ0", "Unit Test Size List", null } }
        };
    }

    public static IEnumerable<string> GetTestDisplayNames() => new List<string> {
        "All Valid", "Duplicate ID", "Missing ID", "Missing Name", "Empty List", "Null List"
    };

And I am getting this message in the test explorer result:

Message: Value cannot be null.

Parameter name: Method GetTestDisplayNames

I searched the web on how to use the DynamicDataDisplayName but I was unable to come with something; all I found is how to use DynamicData


EDIT

I used this code to add a customized names for the test inputs, thanks to

Matěj Pokorný

    [TestMethod]
    [DynamicData(nameof(TestInputs_BeReady), DynamicDataSourceType.Method,
        DynamicDataDisplayName = nameof(GetTestDisplayName))]
    public void Should_DoSomething(object expValue, object[] inputs, string _)
    {
        // Arrange
        // Act
        // Assert
    }
    public static IEnumerable<object[]> TestInputs_BeReady()
    {
        List<string> ITEMS_LIST = new List<string> { "entry_01", "entry_02" };
        List<string> BLANK_LIST = new List<string>();

        return new[]
        {
            new object[] {  true, new object[] { UQID, NAME, ITEMS_LIST }, "All Valid" },
            new object[] { false, new object[] { DPID, NAME, ITEMS_LIST }, "Duplicate ID" },
            new object[] { false, new object[] { BLNK, NAME, ITEMS_LIST }, "Missing ID" },
            new object[] { false, new object[] { UQID, BLNK, ITEMS_LIST }, "Missing Name" },
            new object[] { false, new object[] { UQID, NAME, BLANK_LIST }, "Empty List" },
            new object[] { false, new object[] { UQID, NAME, null }, "Null List" }
        };
    }

1 Answer 1

6

The issue is with GetTestDisplayNames method. You should define it like this

public static string GetTestDisplayNames(MethodInfo methodInfo, object[] values)
{
    var expected = (bool)values[0];
    var inputs = (object[])values[1];
    
    return $"{methodInfo.Name}({expected}, {inputs.Length})";
}

(this is a possible implementation, but you can return a different name of course)

Also, parameter DynamicDataDisplayNameDeclaringType should point to type, where is GetTestDisplayNames method defined. I believe, when you have this method defined in same class as test method (Should_BeReady), this parameter can be skipped.

Sign up to request clarification or add additional context in comments.

4 Comments

Ok. But this won't return customized names like "All Valid", "Duplicate ID", ..., etc. Anyways, thanks. I will poke and tamper with this code to see what else I can do.
Yep, this is not possible, because index of the currently running test case can't be obtained from GetTestDisplayNames method. The best, you can do, is to include something into returned object[] (in TestInputs_BeReady) and then use it in GetTestDisplayNames method...
Yes, this is what I found out during my tests. I will try and modify the question with some code to help others. Thanks @Matěj Pokorný
You can always make the first value in the array the string caption for your test case as convention.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.