Search code examples
c#xunit

Does ClassData in xUnit Test accept arguments? C#


I was writing an unit test for my application. For now I am using Theory with ClassData to create a data-driven unit test. I was wondering is ClassData able to accept parameters so that I can alter the test data based on the input from the test?

Here are some sample code:

This is my data class:

public class InvalidMessageFrame : TheoryData<string, string, string>
{
    public InvalidMessageFrame(string messageType)
    {
        var testData = ReadFromJson(handlerType);

        foreach (var data in testData ?? Enumerable.Empty<InvalidMessageTestModel>())
        {
            Add(data.description, data.message, data.exception);
        }
    }
    
    private IEnumerable<InvalidMessageTestModel> ReadFromJson(string messageType)
    {
        var messageObjectName = messageType switch
        {
            "A" => "Group A",
            "B" => "Group B",
            "C" => "Group C",
            "D" => "Group D",
            _ => throw new ArgumentOutOfRangeException(nameof(messageType), messageType, null)
        };

        var filePath = Path.Combine(Environment.CurrentDirectory, "../../../TestData/InvalidTestData.json");
        var json = File.ReadAllText(filePath);
        var jObject = JObject.Parse(json);
        var testData = jObject[messageObjectName]?.ToObject<IEnumerable<InvalidMessageTestModel>>();

        return testData;
    }
}

Here is my test:

    [Theory]
    [ClassData(typeof(InvalidMessageFrame("A")))]
    public void InvalidTest(string description, string message, string exception)
    {     
    }

As you can see I was trying to let the Class Data accepts an argument so that I can change the test data based on Group ABCD because in my test data json file each of this group is a list of test data. However it seems impossible with my setup because the error shows in the test for this line [ClassData(typeof(InvalidMessageFrame("A")))] and the error are: ) expected.

So if this is not working, I was wondering is there any other method that can achieve the same outcome?

Thank you.


Solution

  • With typeof you are only getting the typeof the class not calling the Constructor so you can only write

    [ClassData(typeof(InvalidMessageFrame))]
    

    And you can build something like this https://andrewlock.net/creating-a-custom-xunit-theory-test-dataattribute-to-load-data-from-json-files/