单元测试静态类

问题描述 投票:20回答:8

场景。语言C#,使用VS2008单元测试框架进行单元测试

我有一个带静态构造函数的静态类和2个方法。我编写了4种测试方法来测试整个类。我的静态构造函数有一些重要的初始化。

现在,如果我串联运行所有4个单元测试用例,则只在开始时调用静态构造函数。在每个测试用例结束时,没有这样的事情

称为静态析构函数,因此构造函数中的状态信息也会被带到下一个单元测试用例。解决方法是什么?

c# .net unit-testing
8个回答
12
投票

最简单的解决方案是向静态类添加“重置”方法,该方法具有破坏它并重构它的等效行为。

您可能有充分的理由在这里使用静态类。但是,由于静力学不能很好地与单元测试相结合,我通常会寻找替代设计。


39
投票
Type staticType = typeof(StaticClassName);
ConstructorInfo ci = staticType.TypeInitializer;
object[] parameters = new object[0];
ci.Invoke(null, parameters);

来自http://colinmackay.scot/2007/06/16/unit-testing-a-static-class/


6
投票

我会将初始化从静态构造函数移动到构造函数调用的方法。通过将此方法设置为内部,您可以从测试中调用此方法以重新初始化该类。

public static class MyClass
{
   public static MyClass()
   {
      initialize();
   }

   internal static void initialize()
   {
      // Do initialization (and cleanup if necessary)
   }

   public static void Method1() {}
   public static void Method2() {}
}

要调用内部方法,您需要使用InternalsVisibleTo属性,如this blog中所述。

您也可以将其设为私有,但之后您需要使用反射来调用它。

但正如Andrew Shepherd所说,你还应该检查静态类是否是这个类的最佳设计。


1
投票

不知道该类的使用情况评论只是使用是有点棘手但不好反正给它一个去。对我来说,上面的声音听起来不仅仅是一个测试问题。

静态类(就像单例一样)基本上是全局函数/变量的集合,这在oop中通常是一件坏事。我会说尝试测试测试问题(尽管现在可能是最简单的)只能修复症状而不是问题。

如果您确实需要静态类,或者它似乎是当时解决问题的最简单方法,我建议您仔细考虑一下所考虑的设计


0
投票

好吧,你没有指定你使用的语言,但如果有办法从测试文件中打开你的静态类,那么我会添加一个假的析构函数,你可以在每次测试后调用它。这样,'析构函数'就会停留在测试类中,而不会停留在生产代码中。


0
投票

您可以使用能够模拟静态类的Typemock's Isolator,因此在每个测试中您都可以“定义”静态操作的方式。

但它不是免费的产品。


0
投票

听起来你正试图测试静态构造函数。这似乎是一个坏主意。

考虑将初始化逻辑提取到单独的(非静态)类中。

为了便于讨论,假设您的静态类名为MySingleton,假设您使用Execute方法创建了一个名为MyInitializer的新类。 MySingleton的静态构造函数可以实例化MyInitializer并调用Execute,它执行所有初始化。

然后您的生产代码可以使用MySingleton,并忽略MyInitializer。另一方面,您的测试可能会忽略MySingleton,并为每个测试快速创建一个新的MyInitializer实例,每次都重新开始。


0
投票

为了完整起见,如果需要重置静态类的非公共字段/变量,也可以通过反射来重置。

using System.Reflection; // or Mono.Reflection

public static class MyClass{
    private static string myString;
}

var newValue = "Potatoes";            
var field = typeof(MyClass).GetField("myString", BindingFlags.Static | BindingFlags.NonPublic);
field.SetValue(null, newValue); // the first null is because the class is static, the second is the new value
© www.soinside.com 2019 - 2024. All rights reserved.