Home > database >  TestCase() in C#- problem with DateTime argument
TestCase() in C#- problem with DateTime argument

Time:03-01

Hey I wrote a test in C# which as argument takes only one DateTime argument. What I would like to do is to add [TestCase(new DateTime(2022, 1, 31))] above my test but when I try to do that I get an error that "An attribute must be a constant expression, typeof expression or array creation expression of an attribute parameter type". What can I do?

CodePudding user response:

Any use of new in the argument list to TestCaseAttribute will get you the same error. Because of the restrictions that C# imposes, NUnit provides TestCaseSourceAttribute.

However, TestCaseSourceAttribute involves more typing and in this case, you can provide a string as the argument. Note that the argument to the test method should still be typed as a DateTime even though you are providing a string. As noted in one of the comments, NUnit is smart enough to convert it.

[TestCase("2022/1/31")]
public void MyTestMethod(DateTime dt)
{
    ...
}

CodePudding user response:

You can't use TestCase for a DateTime, as its not a const. You can either specify it as a string, or try and use TestCaseSource as such

CodePudding user response:

*BTW. There is a new type DateOnly available now in .NET. *

The most trivial case can be solved by using simpler inputs:

[DataTestMethod]
[DataRow(2022, 1, 31)]
public void Test(int year, int month, int day)
{
    Assert.AreEqual(31, new DateOnly(year, month, day));
}

However, DynamicData offers the most flexibility:

public static IEnumerable<object[]> GetTestCases()
{
    var testCases = new List<TestCase>()
    {
        new TestCase()
        {
            DT = new DateOnly(2022, 1, 31),
            ExpectedDay = 31
        },
    };

    return testCases
#if DEBUG //protect from a bad checkin by running all test cases in RELEASE builds
            //.Where(tc => tc.Name.Contains("..."))
#endif
        .Select(tc => new object[] { tc });
}

[TestMethod]
[DynamicData(nameof(GetTestCases), DynamicDataSourceType.Method)]
public void Test(TestCase tc)
{
    Assert.AreEqual(tc.ExpectedDay, tc.DT.Day);
}

public class TestCase
{
    public DateOnly DT { get; init; }

    public int ExpectedDay { get; init; }
}

CodePudding user response:

Suggest using either MemberData property as described in this blog post or replacing it with TheoryData as described here.

Arguments passed to tests must be constants, but you can use either of the above fields to work around that requirement.

  • Related