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

标签 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 不会在上下文之间自动重置状态,那么我应该使用什么策略来确保在我的示例中的情况下重置状态?我是否应该在将所有状态字段设置为 null 的 ContextBase 类上放置一个 Establish lambda?

最佳答案

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

另一种选择是在您的基类上放置一个额外的Establish,但这会从您的上下文中隐藏重要信息 - 您必须导航到基类才能看到一个字段已初始化一定的值(value)。但是 DRY 通常不适用于测试:我更喜欢让基类具有我从派生上下文调用的 protected static 方法(参见 this answer 示例)。

关于mspec - 如何在 MSpec 上下文之间共享/设置静态对象状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14865859/

相关文章:

unit-testing - 使用模拟框架和 MSPEC 时,您在哪里设置 stub

unit-testing - 既然我已经将所有单元测试迁移到 MSpec,我还需要 NUnit 吗?

c# - 如何使用 MSpec 为接口(interface)的所有实现编写通用测试?

resharper - 如何安装 MSpec BDD 框架?

c# - 如何配置 Visual Studio Online 以运行自定义单元测试框架?

c# - 为什么我的 Equals 方法没有被调用?

ReSharper 看不到我的 Machine.Specification 测试

asp.net-mvc - Moq 的意外验证行为

c# - 使用 MSpec(BDD 指南)对 ASP.NET MVC Controller 操作执行非常相似的规范

console - 为什么 Visual Studio 2015 控制台运行程序无法识别 MSpec?