使用模拟框架和 MSPEC 时,您在哪里设置存根

发布于 2024-08-27 12:12:09 字数 397 浏览 7 评论 0原文

我对使用 MSpec 比较陌生,随着我编写越来越多的测试,很明显,为了减少重复,您通常必须按照 Rob Conery 的文章

我是很高兴使用 AssertWasCalled 方法来验证我的期望,但是在哪里设置存根的返回值,我发现在注入我的依赖项的基类中设置上下文很有用,但这(我认为)意味着我需要设置我的在 Cause 委托中存根,感觉不对。

我缺少更好的方法吗?

I am relatively new to using MSpec and as I write more and more tests it becomes obvious to reduce duplication you often have to use a base class for your setup as per Rob Conery's article

I am happy with using the AssertWasCalled method to verify my expectations, but where do you set up a stub's return value, I find it useful to set the context in the base class injecting my dependencies but that (I think) means that I need to set my stubs up in the Because delegate which just feels wrong.

Is there a better approach I am missing?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

本宫微胖 2024-09-03 12:12:09

存根的初始化/设置属于排列阶段。安排阶段用于在您使用系统之前使系统进入已知状态。

在 MSpec 中,排列阶段在 Establish 字段中执行。例如:

public class When_the_temperature_threshold_is_reached
{
    static ITemperatureSensor Sensor;
    static Threshold Threshold;

    Establish context = () =>
        {
            Sensor = MockRepository.GenerateStub<ITemperatureSensor>();
            Sensor
                .Stub(x => x.GetTemperature())
                .Return(42);

            Threshold = new Threshold(Sensor);
        };

    Because of = () => Reached = Threshold.IsReached(40);

    It should_report_that_the_threshold_was_reached =
        () => Reached.ShouldBeTrue();
}

当您使用此类 ITemperatureSensor 编写更多测试时,您应该提取一个执行复杂或重复设置的基类。

public abstract class TemperatureSpecs
{
    protected static ITemperatureSensor CreateSensorAlwaysReporting(int temperature)
    {
        var sensor = MockRepository.GenerateStub<ITemperatureSensor>();
        sensor
            .Stub(x => x.GetTemperature())
            .Return(temperature);

        return sensor;
    }
}

public class When_the_temperature_threshold_is_reached : TemperatureSpecs
{
    // Everything else cut for brevity.
    Establish context = () =>
        {
            Sensor = CreateSensorAlwaysReporting(42);

            Threshold = new Threshold(Sensor);
        };
}

这为您提供了一个优势,您可以从上下文本身影响存根的返回值:您可以通过将尽可能多的信息保留在上下文本地并为基类中的“setup”方法提供一个好名称来实现此目的。

无需在 Because 中指定或期望任何与存根相关的内容。当 Because 运行时,您的系统应该处于无需进一步准备即可运行的状态。

The initialization/setup of stubs belongs to the arrange phase. The arrange phase is used to get the system into a known state before you exercise it.

In MSpec, the arrange phase is performed in Establish fields. For example:

public class When_the_temperature_threshold_is_reached
{
    static ITemperatureSensor Sensor;
    static Threshold Threshold;

    Establish context = () =>
        {
            Sensor = MockRepository.GenerateStub<ITemperatureSensor>();
            Sensor
                .Stub(x => x.GetTemperature())
                .Return(42);

            Threshold = new Threshold(Sensor);
        };

    Because of = () => Reached = Threshold.IsReached(40);

    It should_report_that_the_threshold_was_reached =
        () => Reached.ShouldBeTrue();
}

When you write more tests using that kind of ITemperatureSensor, you should extract a base class that does complicated or repeated setup.

public abstract class TemperatureSpecs
{
    protected static ITemperatureSensor CreateSensorAlwaysReporting(int temperature)
    {
        var sensor = MockRepository.GenerateStub<ITemperatureSensor>();
        sensor
            .Stub(x => x.GetTemperature())
            .Return(temperature);

        return sensor;
    }
}

public class When_the_temperature_threshold_is_reached : TemperatureSpecs
{
    // Everything else cut for brevity.
    Establish context = () =>
        {
            Sensor = CreateSensorAlwaysReporting(42);

            Threshold = new Threshold(Sensor);
        };
}

This gives you the advantage that you can influence the stub's return value from the context itself: You do this by keeping as much information as possible local to the context and provide a good name for the "setup" method in the base class.

There is no need to specifiy or expect anything stub-related in Because. When Because is run, your system should be in a state where it can be exercised without further preparation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文