如何为"T必须是参考类型"编写单元测试?

Sco*_*ock 11 c# tdd unit-testing

考虑:

class MyClass<T> where T : class
{
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,where子句强制执行MyClass只是引用类型的通用的规范.

理想情况下,我应该有一个测试此规范的单元测试.但是,这个单元测试显然不起作用,但它解释了我想要实现的目标:

[Test]
[DoesNotCompile()]
public void T_must_be_a_reference_type()
{
    var test = new MyClass<int>();
}
Run Code Online (Sandbox Code Playgroud)

我可以做些什么来测试不允许代码编译实现的规范?

编辑:

更多信息:好的,所以我这样做的理由(哈哈)是我一直在遵循TDD方法,除非你有一个失败的单元测试,否则你不能编写任何代码.假设你有这个:

class MyClass<T> { }
Run Code Online (Sandbox Code Playgroud)

除非T是一个类,否则你可以写什么测试会失败?有点像default(T) == null

进一步编辑:

因此,在这个"根原因分析"后,问题是,我是靠着default(T)null这一类的消费者,以隐式方式.我能够将该消费者代码重构为另一个类,并在那里指定一个泛型类型限制(限制它class),这有效地使得代码无法编译,如果有人要删除我上面讨论的类的限制.

Jon*_*eet 25

为什么你需要进行单元测试呢?你是否为某种方法编写单元测试?

public void Foo(string x)
Run Code Online (Sandbox Code Playgroud)

检查它只能采取字符串,而不是整数?如果没有,你认为差异是什么?

编辑:只是稍微不那么异想天开:在这种情况下,规范由声明验证.测试通常应该测试行为.这是我喜欢的代码合同之一:我觉得没有必要对合同进行单元测试,除非它们表达了复杂的东西 - 在这种情况下,我要测试的是复杂性,而不是"合同强制执行" .

编辑:回答问题编辑:

除非T是一个类,否则你可以写什么测试会失败?

可以这样写:

Type definition = typeof(MyClass<>);
Assert.Throws<ArgumentException>(() => definition.MakeGenericType(typeof(int)));
Run Code Online (Sandbox Code Playgroud)

然而,这似乎违背了测试的真正目的......

  • @Scott:我不认为TDD应该要求这样做.同样,您不会编写测试以确保您不能传递无效参数.您的测试驱动设计的*正*侧("我可以使用参考类型参数")但不一定是*负*侧.最终所有的测试都应该是务实的 - 但是测试编译器*不是一个实用的时间,IMO. (6认同)
  • @Scott Whitlock - 但只是代码编译**是**你的测试. (2认同)

Pie*_*kel 9

您不应该测试编译器是否正常工作.如果在代码中指定它,这就足够了.从代码的角度来看,这与此大致相同:

[Test]
public void Test_whether_add_works()
{
    int i = 1 + 2;

    Assert.AreEqual(3, i);
}
Run Code Online (Sandbox Code Playgroud)

  • '[Test] public void Running1984(){Assert.AreEqual(5,2 + 2); }" (4认同)