C# 单元测试静态类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/973556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
UnitTesting Static Classes
提问by SNA
Scenario. Language C#, Unit testing using VS2008 Unit testing framework
设想。语言 C#,使用 VS2008 单元测试框架进行单元测试
I have a static class with a static constructor and 2 methods. I have 4 test methods written to test the entire class. My Static Constructor has some important initializations.
我有一个带有静态构造函数和 2 个方法的静态类。我编写了 4 个测试方法来测试整个类。我的静态构造函数有一些重要的初始化。
Now if I run all the 4 unit test cases in tandem, the static constructor will be called only at the beginning. At the end of each test case, there is no such thing
现在,如果我同时运行所有 4 个单元测试用例,静态构造函数将仅在开始时调用。在每个测试用例结束时,没有这样的事情
called static destructor, So the state info in the constructor gets carried to the next unit test case also. What is the workaround for this.
称为静态析构函数,因此构造函数中的状态信息也会被传送到下一个单元测试用例。对此有什么解决方法。
采纳答案by Andrew Shepherd
The simplest solution is to add a "Reset" method to your static class, which would have the equivalent behaviour of destructing it and reconstructing it.
最简单的解决方案是向您的静态类添加一个“重置”方法,这将具有破坏它和重建它的等效行为。
There may be a valid reason why you are using a static class here. However, because statics don't play nicely with unit tests, I usually search for an alternative design.
在这里使用静态类可能是有正当理由的。但是,因为静态不能很好地与单元测试配合使用,所以我通常会寻找替代设计。
回答by cloudhead
Well, you didn't specify which language you were using, but if there is a way to open up your static class from within the test file, then I would add a fake destructor to it, which you can call after each test. That way, the 'destructor' stays in the test class, and out of your production code.
好吧,您没有指定您使用的是哪种语言,但是如果有办法从测试文件中打开静态类,那么我会向其中添加一个假析构函数,您可以在每次测试后调用它。这样,“析构函数”就会留在测试类中,而不会出现在您的生产代码中。
回答by Aaron Powell
You could use Typemock's Isolatorwhich is capable of mocking static classes, so in each test you can "define" how the static will be operating.
您可以使用能够模拟静态类的Typemock 隔离器,因此在每个测试中您可以“定义”静态将如何操作。
It's not a free product though.
虽然它不是免费产品。
回答by Joe White
It sounds like you're trying to test the static constructor. This seems like a bad idea.
听起来您正在尝试测试静态构造函数。这似乎是个坏主意。
Consider extracting the initialization logic into a separate (non-static) class instead.
考虑将初始化逻辑提取到一个单独的(非静态)类中。
For the sake of discussion, let's say your static class is called MySingleton, and let's say you create a new class called MyInitializer, with an Execute method. MySingleton's static constructor could instantiate MyInitializer and call Execute, which does all the initialization.
为便于讨论,假设您的静态类名为 MySingleton,假设您创建了一个名为 MyInitializer 的新类,并带有一个 Execute 方法。MySingleton 的静态构造函数可以实例化 MyInitializer 并调用执行所有初始化工作。
Then your production code could use MySingleton, and ignore MyInitializer. Your tests, on the other hand, could ignore MySingleton, and merrily create a new MyInitializer instance for each test, getting a fresh start each time.
然后您的生产代码可以使用 MySingleton,而忽略 MyInitializer。另一方面,您的测试可以忽略 MySingleton,并为每个测试愉快地创建一个新的 MyInitializer 实例,每次都重新开始。
回答by Rune FS
With out knowing the usage of the class commenting on just the usage is of cause a bit tricky but ill give it a go anyways. To me the above sounds like a smell more than a testing problem.
在不知道类的用法的情况下,仅对用法进行评论会有点棘手,但无论如何都不能试一试。对我来说,以上听起来更像是一种气味,而不是测试问题。
A static class (just as singletons) are basically a collection of global functions/variables which generally is a bad thing in oop. I'd say trying to test the test issue is (eventhough probably the easiest right now) only fixing the symptom but not the problem.
静态类(就像单例一样)基本上是全局函数/变量的集合,这在 oop 中通常是一件坏事。我会说尝试测试测试问题(尽管现在可能是最简单的)只是解决了症状,而不是问题。
I'd suggest to take a look at the desing a concidere if you really need the static class or if it just seemed like the easiest way to fix a problem at the time
如果您真的需要静态类,或者它似乎是当时解决问题的最简单方法,我建议您查看设计方案
回答by BengtBe
I would move the initialization from the static constructor to a method that is called by the constructor. By making this method internal, you can then call this method from your tests to reinitialize the class.
我会将初始化从静态构造函数移动到由构造函数调用的方法。通过将此方法设置为internal,您可以从测试中调用此方法以重新初始化该类。
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() {}
}
In order to call the internal methods you need to use the InternalsVisibleToattribute, as described in this blog.
为了调用内部方法,您需要使用InternalsVisibleTo属性,如本博客所述。
You can also make it private, but then you need to use reflection to call it.
您也可以将其设为私有,但随后您需要使用反射来调用它。
But as Andrew Shepherd said, you should also check if a static class is the best design of this class.
但正如 Andrew Shepherd 所说,您还应该检查静态类是否是此类的最佳设计。
回答by rob
Type staticType = typeof(StaticClassName);
ConstructorInfo ci = staticType.TypeInitializer;
object[] parameters = new object[0];
ci.Invoke(null, parameters);
from http://colinmackay.scot/2007/06/16/unit-testing-a-static-class/
来自http://colinmackay.scot/2007/06/16/unit-testing-a-static-class/
回答by dtasev
For the sake of completeness, if you need to reset a non-public field/variable of a static class, it is also possible to do so via reflection.
为了完整起见,如果您需要重置静态类的非公共字段/变量,也可以通过反射来实现。
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