NUnit 3.0 TestCase const自定义对象参数

时间:2015-12-03 20:43:59

标签: c# nunit

我已经编写了类SomeObject,我想在我的const中定义此对象的TestCase实例以保留/重用。我应该如何重写下面的代码来实现这种行为?

[TestFixture]
public class SomeObjectTests
{
    private const SomeObject item0 = new SomeObject(0.0); // doesn't work

    [TestCase(item0, ExpectedResult = 0.0)]
    public double TestSomeObjectValue(SomeObject so)
    {
        return so.Value;
    }

    [TestCase(item0, ExpectedResult = "0.0")]
    public string TestSomeObjectValueString(SomeObject so)
    {
        return so.ValueString;
    }
}

我收到以下错误消息:

  

除string之外的引用类型的const字段只能用null初始化。

3 个答案:

答案 0 :(得分:6)

实现您要做的事情的更好方法是使用TestCaseSource。在你的情况下:

[TestFixture]
public class SomeObjectTests
{
    [TestCaseSource(typeof(TestSomeObject),"TestCasesValue")]
    public double TestSomeObjectValue(SomeObject so)
    {
        return so.Value;
    }

    [TestCaseSource(typeof(TestSomeObject),"TestCasesValueString")]
    public string TestSomeObjectValueString(SomeObject so)
    {
        return so.ValueString;
    }
}

public class TestSomeObject
{
  public static IEnumerable TestCasesValue
  {
    get
    {
        yield return new TestCaseData( new SomeObject(0.0) ).Returns( 0.0 );
        yield return new TestCaseData( new SomeObject(1.0) ).Returns( 1.0 );
    }
  }

  public static IEnumerable TestCasesValueString
  {
    get
    {
        yield return new TestCaseData( new SomeObject(0.0) ).Returns( "0.0" );
        yield return new TestCaseData( new SomeObject(1.0) ).Returns( "1.0" );
    }
  }
}

答案 1 :(得分:4)

C# language spec, §10.3说(强调我的):

  

当需要常量值的符号名称时,但在常量声明中不允许该值的类型时,或者在编译时无法通过常量表达式计算该值时, a可以使用readonly字段(Section 10.4.2)代替

令人讨厌的是,由于属性也有一定的限制,这一点更加复杂 - 请参阅C# language spec, §17.2(再次强调我的):

  

如果以下所有语句都为真,则表达式E是attribute-argument-expression:

     
      
  • E的类型是属性参数类型(第17.1.3节)。

  •   
  • 在编译时,E的值可以解析为以下之一:

         
        
    • 常数值。

    •   
    • System.Type对象。

    •   
    • 属性 - 参数表达式的一维数组。

    •   
  •   

其中§17.1.3:“属性参数类型”表示 1

  

属性类的位置和命名参数的类型仅限于属性参数类型,它们是:

     
      
  • 以下类型之一:boolbytechardoublefloatintlongshortstring
  •   
  • 类型object
  •   
  • 类型System.Type
  •   
  • 枚举类型,前提是它具有公共可访问性,嵌套类型(如果有)也具有公共可访问性(第17.2节)。
  •   
  • 上述类型的一维数组。
  •   

1 :引用的文本来自旧版本的C#规范 - 在C# 5.0版本中,提到了另外四种类型:sbyte,{{1} },uintulong

换句话说,你能做的最好就是:

ushort

这样,属性的参数是编译时常量,[TestFixture] public class SomeObjectTests { private static readonly SomeObject item0 = new SomeObject(0.0); private static SomeObject getObject(string key) { if ( key == "item0" ) return item0; throw new ArgumentException("Unknown key"); } [TestCase("item0", ExpectedResult = 0.0)] public double TestSomeObjectValue(string key) { SomeObject so = getObject(key); return so.Value; } [TestCase("item0", ExpectedResult = "0.0")] public string TestSomeObjectValueString(string key) { SomeObject so = getObject(key); return so.ValueString; } } 方法可以处理获取getObject实例。

答案 2 :(得分:0)

  1. 只需删除const即可。它将是每个实例的私有变量
  2. 使它成为静态,它将是该类的单例。
  3. 用readonly替换const。这会将此标记为不应混淆的内容。