C# 如何强制MSTestMethod在运行前重置所有单例/静态?

C# 如何强制MSTestMethod在运行前重置所有单例/静态?,c#,unit-testing,visual-studio-2008,mstest,appdomain,C#,Unit Testing,Visual Studio 2008,Mstest,Appdomain,我在VisualStudio2008中使用MSTEST。如何让某个测试类中的每个单元测试方法都像第一个测试一样运行,以便在运行每个测试之前重置所有全局状态?我不想使用TestInitialize、ClassInitialize、AssemblyInitialize等明确清理世界。例如: [TestClass] public class MyClassTests { [TestMethod] public void Test1() { // The "Inst

我在VisualStudio2008中使用MSTEST。如何让某个测试类中的每个单元测试方法都像第一个测试一样运行,以便在运行每个测试之前重置所有全局状态?我不想使用TestInitialize、ClassInitialize、AssemblyInitialize等明确清理世界。例如:

[TestClass]
public class MyClassTests
{
    [TestMethod]
    public void Test1()
    {
       // The "Instance" property creates a new instance of "SomeSingleton"
       // if it hasn't been created before.
       var i1 = SomeSingleton.Instance;
       ...
    }
    [TestMethod]
    public void Test2()
    {
       // When I select "Test1" and "Test2" to run, I'd like Test2
       // to have a new AppDomain feel so that the static variable inside
       // of "SomeSingleton" is reset (it was previously set in Test1) on
       // the call to ".Instance"
       var i2 = SomeSingleton.Instance;
       // some code
    }
虽然在这个主题上出现了一个例子,但它只是澄清了测试不是并行运行的。我意识到测试是串行运行的,但是似乎没有一种方法可以显式地强制每个方法使用一个新的AppDomain(或者相当于清除所有状态)


理想情况下,我只想为我的单元测试的一小部分指定这种行为,这样我就不必为不关心全局状态的测试(我的绝大多数测试)支付创建新AppDomain的罚款。

我们的MSTests也出现了类似的问题。我们通过在需要它的特定测试的开始和结束时调用函数来处理它

我们正在应用程序配置中存储测试过期日期。三项测试需要该日期进入特定范围,以确定适当的值。按照应用程序的设置方式,只有在会话中没有分配值时,才会重置配置值。因此,我们创建了两个新的私有静态函数——一个用于显式地将配置值设置为指定的日期,另一个用于在测试运行后从会话中清除该日期。在我们的三个测试中,我们调用了这两个函数。当下一个测试运行时,应用程序会看到日期的空值,并从配置文件中重新提取该值


我不确定这是否有帮助,但这就是我们解决类似问题的方法。

我认为您正在寻找Testentialize属性和TestCleanUp属性。下面是一个MSDN博客,展示了执行顺序。最后,我编写了一个助手,使用反射调用不同AppDomain下的单元测试。它提供了我所需要的隔离

在MSDN的论坛上,我们展示了如果您只有一些需要重置的静态数据,如何处理这种情况。确实提到了一些选项(例如使用反射和反射)


我继续欢迎任何进一步的想法,特别是如果我缺少MSTEST的一些明显的东西。

在测试中添加一个使用反射删除singleton实例的帮助器(您也可以向singleton添加一个reset方法,但我会担心它的使用)。比如:

public static class SingletonHelper {
            public static void CleanDALFactory() 
            {
                    typeof(DalFactory)
                        .GetField("_instance",BindingFlags.Static | BindingFlags.NonPublic)
                        .SetValue(null, null);
            }
}

在TestInitialize方法中调用此函数。[我知道这是“清理世界”,但您只需在每个单独的助手中编写一次该方法,它非常简单,并为您提供显式控制]

感谢您的回答。我一直在寻找一种无需明确清除每个变量就能清理世界的方法,但我不确定这是否可行。似乎您可以在测试类中使用[TestInitialize]。谢谢您的回答。我认为我必须使用反射的组合来迭代静态字段,大致上就是您在这里描述的内容。类似于“NullifyStaticFields(Type t)”的代码,以使其可重用