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

时间:2010-03-29 19:26:37

标签: unit-testing rhino-mocks bdd mspec

我使用MSpec相对较新,随着我编写越来越多的测试,显然减少重复,你经常需要根据Rob Conery's article使用基类进行设置

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

我缺少更好的方法吗?

1 个答案:

答案 0 :(得分:7)

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

在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运行时,您的系统应该处于无需进一步准备即可行使的状态。