有几个相同类型的 nUnit 单元测试,检查十进制字符串的解析(这是 c# 中推荐的货币单位类型):
[Test]
public void Test3()
{
// Arrange
var input = "1,234.56";
// Act
var result = MoneyParser.Parse(input);
// Assert
Assert.AreEqual(1234.56m, result);
}
好吧,我因此想通过悬挂 TestCase 属性将所有这些优雅地打包到一个方法中:
[TestCase("1234", 1234m)]
[TestCase("1234.56", 1234.56m)]
[TestCase("1234,56", 1234.56m)]
[TestCase("1 234.56", 1234.56m)]
[TestCase("1 234,56", 1234.56m)]
[TestCase("1,234.56", 1234.56m)]
public void Test(string input, decimal expected)
{
var result = MoneyParser.Parse(input);
Assert.AreEqual(expected, result);
}
但是,只能在属性中使用原始类型,并且带有小数的代码甚至无法编译 - 它会给出错误:
错误 CS0182 属性参数必须是属性参数类型的常量表达式、typeof 表达式或数组创建表达式
你如何绕过这个障碍并编写一个可读的测试?想到的唯一选择是在输入时将预期设置为字符串,在测试中进行转换 - 这并不令人愉快,因为很容易用无效数据破坏文本(没有类型安全性),或者因为您必须通过不必要的转换来混淆代码。
由于在 C# 中
double可以将类型隐式转换为类型,因此您可以简单地删除属性中所有-decimal值的后缀。在这种情况下不会损失准确性(如有必要,可以轻松检查)。mdecimalTestCase最终测试将如下所示:
唯一的缺点:查看这些测试用例,您不能说该方法完全采用
decimal了参数。在其他情况下,单元测试将因不必要的检查、显式转换等而过度生长。
您可以尝试不通过属性通过测试,使用
TestCaseSource. 它会很丑,但它会起作用:好处:在一定程度上,更改测试时保留了类型安全。
缺陷:
object[]破解代码很容易;