如何使用decimal.MaxValue进行测试?

时间:2014-08-04 09:21:59

标签: c# unit-testing nunit decimal

考虑以下测试:

public void FooTest(decimal? val)
{
    Check.That(true).IsTrue();
}

我想使用极端值(即MaxValueMinValue)运行此测试。

[TestCase(decimal.MaxValue)]

这会输出以下错误:属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式

[TestCase(79228162514264337593543935)]

我现在得到这个:积分常数太大

最后一次绝望的尝试:

[TestCase(79228162514264337593543935M)]

显然我因为演员而得到这个:属性参数必须是属性参数类型的常量表达式,typeof表达式或数组创建表达式

如何用decimal.MaxValue作为参数编写单元测试?我可以为这个有问题的案例编写一个特定的测试,但我想知道是否有办法写这样的TestCase

3 个答案:

答案 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 :(