我编写了这个类SomeObject
,我想定义一个const
这个对象的实例来保存/重用我的TestCase
s.我应该如何重写下面的代码来实现这种行为?
[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初始化.
Daniel Rose.. 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" ); } } }
Wai Ha Lee.. 5
在C#语言规范,10.3节说(重点煤矿):
当需要一个常量值的符号名称,但是当常量声明中不允许该值的类型时,或者当常量表达式不能在编译时计算该值时,则使用一个
readonly
字段(第10.4.2节))可以代替。
令人烦恼的是,属性也有一定的限制,这使情况更加复杂-请参阅C#语言规范§17.2(再次强调我的):
如果以下所有语句为真,则表达式E为attribute-argument-expression:
E的类型是属性参数类型(第17.1.3节)。
在编译时,E的值可以解析为以下值之一:
恒定值。
一个System.Type对象。
属性参数表达式的一维数组。
其中§17.1.3:“ 属性参数类型 ”说1:
属性类的位置和命名参数的类型仅限于属性参数类型,它们是:
其中以下类型:
bool
,byte
,char
,double
,float
,int
,long
,short
,string
。类型
object
。类型
System.Type
。枚举类型,只要它具有公共可访问性,并且嵌套的类型(如果有)也具有公共可访问性(第17.2节)。
上述类型的一维数组。
1:引用的文字是从旧版本的C#规范的-在C#5.0版,四个附加类型提及:sbyte
,uint
,ulong
,和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
方法可以处理获取SomeObject
实例。
实现您要做的事情的更好方法是使用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" ); } } }
在C#语言规范,10.3节说(重点煤矿):
当需要一个常量值的符号名称,但是当常量声明中不允许该值的类型时,或者当常量表达式不能在编译时计算该值时,则使用一个
readonly
字段(第10.4.2节))可以代替。
令人烦恼的是,属性也有一定的限制,这使情况更加复杂-请参阅C#语言规范§17.2(再次强调我的):
如果以下所有语句为真,则表达式E为attribute-argument-expression:
E的类型是属性参数类型(第17.1.3节)。
在编译时,E的值可以解析为以下值之一:
恒定值。
一个System.Type对象。
属性参数表达式的一维数组。
其中§17.1.3:“ 属性参数类型 ”说1:
属性类的位置和命名参数的类型仅限于属性参数类型,它们是:
其中以下类型:
bool
,byte
,char
,double
,float
,int
,long
,short
,string
。类型
object
。类型
System.Type
。枚举类型,只要它具有公共可访问性,并且嵌套的类型(如果有)也具有公共可访问性(第17.2节)。
上述类型的一维数组。
1:引用的文字是从旧版本的C#规范的-在C#5.0版,四个附加类型提及:sbyte
,uint
,ulong
,和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
方法可以处理获取SomeObject
实例。