C# 中的 TestCase() - DateTime 参数的问题
TestCase() in C#- problem with DateTime argument
嘿,我用 C# 编写了一个测试,作为参数只接受一个 DateTime 参数。我想做的是在我的测试之上添加 [TestCase(new DateTime(2022, 1, 31))]
但是当我尝试这样做时我得到一个错误“属性必须是属性参数类型的常量表达式、typeof 表达式或数组创建表达式” .我能做什么?
建议使用 MemberData
属性,如 this blog post or replacing it with TheoryData
as described here 中所述。
传递给测试的参数必须是常量,但您可以使用上述任一字段来解决该要求。
*顺便说一句。 .NET 中现在提供了一种新类型 DateOnly
。 *
最简单的情况可以通过使用更简单的输入来解决:
[DataTestMethod]
[DataRow(2022, 1, 31)]
public void Test(int year, int month, int day)
{
Assert.AreEqual(31, new DateOnly(year, month, day));
}
但是,DynamicData
提供了最大的灵活性:
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; }
}
在 TestCaseAttribute
的参数列表中使用任何 new
都会导致同样的错误。由于 C# 强加的限制,NUnit 提供 TestCaseSourceAttribute
.
但是,TestCaseSourceAttribute
涉及更多的输入,在这种情况下,您可以提供一个字符串作为参数。请注意,即使您提供的是字符串,测试方法的参数仍应键入为 DateTime。正如其中一条评论所述,NUnit 足够聪明,可以将其转换。
[TestCase("2022/1/31")]
public void MyTestMethod(DateTime dt)
{
...
}
如果您需要多次测试,这就是解决方案
Nunit documentation。如果你没有多个参数来测试从外部传递值的意义不大,你可以在测试中定义一个变量
private static DateTime[] source = new DateTime[]
{
new DateTime(2021,1,12),
new DateTime(2022,2,12),
new DateTime(1988,4,4)
};
[Test, TestCaseSource(nameof(source))]
public void XXX(DateTime dt)
{
}
嘿,我用 C# 编写了一个测试,作为参数只接受一个 DateTime 参数。我想做的是在我的测试之上添加 [TestCase(new DateTime(2022, 1, 31))]
但是当我尝试这样做时我得到一个错误“属性必须是属性参数类型的常量表达式、typeof 表达式或数组创建表达式” .我能做什么?
建议使用 MemberData
属性,如 this blog post or replacing it with TheoryData
as described here 中所述。
传递给测试的参数必须是常量,但您可以使用上述任一字段来解决该要求。
*顺便说一句。 .NET 中现在提供了一种新类型 DateOnly
。 *
最简单的情况可以通过使用更简单的输入来解决:
[DataTestMethod]
[DataRow(2022, 1, 31)]
public void Test(int year, int month, int day)
{
Assert.AreEqual(31, new DateOnly(year, month, day));
}
但是,DynamicData
提供了最大的灵活性:
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; }
}
在 TestCaseAttribute
的参数列表中使用任何 new
都会导致同样的错误。由于 C# 强加的限制,NUnit 提供 TestCaseSourceAttribute
.
但是,TestCaseSourceAttribute
涉及更多的输入,在这种情况下,您可以提供一个字符串作为参数。请注意,即使您提供的是字符串,测试方法的参数仍应键入为 DateTime。正如其中一条评论所述,NUnit 足够聪明,可以将其转换。
[TestCase("2022/1/31")]
public void MyTestMethod(DateTime dt)
{
...
}
如果您需要多次测试,这就是解决方案 Nunit documentation。如果你没有多个参数来测试从外部传递值的意义不大,你可以在测试中定义一个变量
private static DateTime[] source = new DateTime[]
{
new DateTime(2021,1,12),
new DateTime(2022,2,12),
new DateTime(1988,4,4)
};
[Test, TestCaseSource(nameof(source))]
public void XXX(DateTime dt)
{
}