C# 在NUnit中测试不可编译的代码

C# 在NUnit中测试不可编译的代码,c#,.net,unit-testing,nunit,C#,.net,Unit Testing,Nunit,我有一个类,在它有效之前,它应该一直填充某个成员。为了实现这一点,类没有默认构造函数,而是有一个接受所需成员值的构造函数。设置如下所示: public class MyClass { public string Owner { get; protected set; } public MyClass(string owner) { this.Owner = owner; } } 现在我想编写一个测试来确保实际上没有默认构造函数,因此如果将来添加一个构造函数,我们会想起

我有一个类,在它有效之前,它应该一直填充某个成员。为了实现这一点,类没有默认构造函数,而是有一个接受所需成员值的构造函数。设置如下所示:

public class MyClass
{
  public string Owner { get; protected set; }

  public MyClass(string owner)
  {
    this.Owner = owner;
  }
}

现在我想编写一个测试来确保实际上没有默认构造函数,因此如果将来添加一个构造函数,我们会想起没有一个默认构造函数的原因,并被迫考虑这样做的影响。尽管很明显,在测试中调用默认构造函数不会失败,也不会编译

有没有一个好方法可以在不修改我原来的类的情况下完成这种测试?如果不是,我想我可以实现一个抛出异常的默认构造函数。我唯一的犹豫是调用默认构造函数现在变成了可编译代码,然后我们必须依靠其他测试来确保这样的代码不会被编写

想法?

您可以调用以尝试运行默认构造函数,并断言抛出了
MissingMethodException

[Test]
[ExpectedException(typeof(MissingMethodException))
public void ShouldBeNoDefaultConstructorForMyClass()
{
    Activator.CreateInstance(typeof(MyClass));
}

您可以使用反射来检查类是否有无参数构造函数,如果有,则测试失败。我将创建一个默认构造函数,将其标记为private,并将文档放在那里。那么你这样做的理由就不会隐藏在什么地方了。您必须意识到,您将放弃一些需要无参数构造函数的序列化功能。

是的。一个好方法是使用反射在try/catch中尝试无参数构造函数

在这种情况下,我更喜欢这种方式,而不是单元测试概念,因为单元测试往往会半途而废,而当您试图更改它时,带有注释的代码就在您面前。毕竟,在这种情况下,您并不是要测试功能,而是要测试编程风格或编程规范,而这并不是单元测试的真正目的。我更喜欢两者的结合。我总是假设测试应该记录业务原因。不过,测试的好处在于,它通过破坏构建来强制遵从性。文档并没有。无论您提出什么解决方案,我都建议您在类本身中记录缺少的默认构造函数的重要性,这样您就不会依赖于将来可能运行或可能不运行的测试。当然,下一个开发人员可能会忽略这些注释(另一个级别:-)测试应该在构建服务器上运行,因此如果失败,构建就会中断。依赖开发人员运行测试总是一个坏主意-如果没有持续集成,单元测试将永远无法工作。@womp:同意,但在生成服务器上运行或不运行单个测试仍然可以启用/禁用,这就是我的观点。依靠在项目的其他部分进行的测试将永远持续进行并非不合理,但也不能保证。至少通过课堂上的评论,你正在尽一切努力让人们意识到这一点。可能比测试本身更重要,因为未来的开发人员不知道与特定测试存在相关的“为什么”。我想涵盖所有的基础是我的观点。测试应该被记录下来。当测试失败时,人们首先需要知道测试的目的是什么。所以我同意,但我更喜欢测试和文档的结合。-1,当你可以简单地断言它不存在时,为什么要调用它?+1-正是我所需要的。要回答约翰,你可以用任何一种方法。既然人们可以选择一个或另一个,并且都能回答所问的问题,为什么仅仅因为这不是你选择的道路,你就会选择一个有效的答案呢?
ConstructorInfo ci = typeof(MyClass).GetConstructor(Type.EmptyTypes);
Assert.IsNull(ci);