如何在MSpec上下文之间共享/设置静态对象状态?

时间:2013-02-14 00:32:13

标签: mspec

在编写一些MSpec BDD测试时,我遇到了一个场景,我希望失败的测试通过,但只有当我运行所有测试时。当我单独运行测试时,它按预期失败了。经过一些调查后,我发现在第二次测试运行之前,先前测试中设置的某些状态没有被重置,这导致第二次测试在我预期失败时通过。以下设计的代码重现了该场景:

public class ContextBase
{
    protected static object state;
}

public class Context_a : ContextBase
{
    Establish context = () => { state = new object(); };

    It should_set_state = () => state.ShouldNotBeNull();
}

public class Context_b : ContextBase
{
    Establish context = () => {  };

    It should_set_state = () => state.ShouldNotBeNull();
}

这两个测试都通过,因为Context_a在Context_b之前执行,并且在执行Context_B时,仍然设置了在Context_A中设置的状态。如果单独运行Context_B,则测试将失败,因为尚未设置状态。有趣的是,如果从Context_B中删除空的Establish语句,则Context_B将始终按预期失败。

我对MSpec比较陌生,这种行为让我感到惊讶。我假设在执行每个上下文之间会重置这样的状态。也许我错过了一些东西......我是否正确地构建了这些测试?如果MSpec没有自动在上下文之间重置这样的状态,那么我应该使用什么策略来确保在我的示例中的情况下重置状态?我应该在ContextBase类上放置一个建立lambda,将所有状态字段设置为null吗?

1 个答案:

答案 0 :(得分:2)

MSpec在执行上下文之间不会“重置”静态。它遵循您从正常静态变量中了解的行为,即除非您手动执行,否则它们在应用程序(即测试运行)运行时不会重新初始化。最好初始化每个上下文的Establish中的所有字段。

另一种选择是在你的基类上增加一个Establish,但这会隐藏你的上下文中的重要信息 - 你必须导航到基类才能看到一个字段是用某个值初始化的。但是DRY一般不适用于测试:我更喜欢使用protected static方法的基类,我可以从派生的上下文中调用它(参见this answer的例子)。