繁体   English   中英

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

[英]How to write a unit test for “T must be a reference type”?

考虑:

class MyClass<T> where T : class
{
}

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

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

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

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

编辑

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

class MyClass<T> { }

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

进一步编辑

因此,在对此进行“根本原因分析”之后,问题在于我以隐式方式依赖default(T)在此类的使用者中为null 我能够将该消费者代码重构为另一个类,并在那里指定一个泛型类型限制(将其限制为class ),这有效地使得该代码无法编译,如果有人要删除我上面讨论的类的限制。

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

public void Foo(string x)

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

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

编辑:回答问题编辑:

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

可以这样写:

Type definition = typeof(MyClass<>);
Assert.Throws<ArgumentException>(() => definition.MakeGenericType(typeof(int)));

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

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

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

    Assert.AreEqual(3, i);
}

这是一个很好的问题! 非常同意您的测试驱动方法。 你正在努力的实际上是两种范式的冲突。 旧程序应该证明程序应该被证明是正确的,使用数学而不运行它们(我们专业的数学祖先遗产)和程序化的新范例应该通过执行示例用例(即测试)来证明是正确的。 所以你要尝试的是将新范式的实践应用于旧范例的工件,当然这不会真正起作用......

更多关于类型和测试的二分法,请参阅Chris Smith撰写的这篇优秀文章, http: //web.archive.org/web/20080822101209/http: //www.pphsg.org/cdsmith/types.html

你在写一个正确的单元测试吗? 看起来你要测试C#编译器而不是你的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM