我已经编写了类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初始化。
答案 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 :
属性类的位置和命名参数的类型仅限于属性参数类型,它们是:
- 以下类型之一:
bool
,byte
,char
,double
,float
,int
,long
,short
,string
。- 类型
object
。- 类型
System.Type
。- 枚举类型,前提是它具有公共可访问性,嵌套类型(如果有)也具有公共可访问性(第17.2节)。
- 上述类型的一维数组。
1 :引用的文本来自旧版本的C#规范 - 在C# 5.0版本中,提到了另外四种类型:sbyte
,{{1} },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
实例。
答案 2 :(得分:0)