考虑以下测试:
public void FooTest(decimal? val)
{
Check.That(true).IsTrue();
}
我想使用极端值(即MaxValue
和MinValue
)运行此测试。
[TestCase(decimal.MaxValue)]
这会输出以下错误:属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式
[TestCase(79228162514264337593543935)]
我现在得到这个:积分常数太大
最后一次绝望的尝试:
[TestCase(79228162514264337593543935M)]
显然我因为演员而得到这个:属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式
如何用decimal.MaxValue
作为参数编写单元测试?我可以为这个有问题的案例编写一个特定的测试,但我想知道是否有办法写这样的TestCase
。
答案 0 :(得分:17)
现在所有其他人已经说过,为什么会出现这个问题,您的代码应该使用TestCaseSource
属性来编写测试:
private static object[] TestValues =
{
new object[]{ Decimal.MaxValue },
new object[]{ Decimal.MinValue }
};
[TestCaseSource("TestValues")]
public void FooTest(decimal value)
{
Assert.That(value, Is.EqualTo(Decimal.MaxValue));
}
答案 1 :(得分:6)
您是尝试使用[TestCase(Decimal.MaxValue)]
还是使用像[TestCase(1m)]
这样的文字并不重要。两者都不会起作用。
根据C#规范(17.1.3,属性参数类型):
属性类的位置和命名参数的类型仅限于属性参数类型,它们是:
•以下类型之一:bool,byte,char,double,float,int,long,sbyte,short,string,uint,ulong,ushort。
•类型对象。
•System.Type类型 •枚举类型,前提是它具有公共可访问性,并且嵌套类型(如果有)也具有公共可访问性(第17.2节)。
•上述类型的一维数组。
注意第一个列表项中没有小数。
错误消息有点误导,因为同样的规范也说decimal
可以是常量表达式(7.19)。
但是如果你在创建decimal
时查看IL代码,你会发现它实际上调用了一个构造函数调用:newobj System.Decimal..ctor
。这与其他文字不同,例如ldc.r8 33 33 33 33 33 33 F3 3F
的{{1}}。
答案 2 :(得分:5)
Decimal.MaxValue不是常量,而是static
readonly
字段。这意味着您无法在属性中使用它,因为属性需要常量。你必须对它进行硬编码。
Visual studio will pretend it as a const
but it is actually not
bool isConstant = typeof (decimal)
.GetField("MaxValue", BindingFlags.Static | BindingFlags.Public)
.IsLiteral;
//isConstant will be false :(