When using mocking structure and MSPEC where you install your stubs

I'm relatively new to using MSpec, and as I write more and more tests, it becomes obvious that to reduce duplication you often have to use the base class for your installation, according to Rob Conir’s article

I am pleased to use the AssertWasCalled method to test my expectations, but where you set the return value of the stub, I find it useful to set the context in the base class introducing my dependencies, but this (I think) means I need to set my stubs in the delegate "Because it's just not right. "

Is there a better approach that I am missing?

+3
source share
1 answer

Initialization / setting of stubs refers to the arrangement phase. The arrangement phase is used so that the system falls into a known state before executing it.

In MSpec, the arrangement phase is performed in the fields Establish. For instance:

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 this type ITemperatureSensor, you must extract a base class that does complex or repetitive tuning.

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 return value of the stub from the context itself: you do this by storing as much information as possible locally for the context and providing a good name for the "install" method in the base class.

-, ​​ Because. Because, , .

+7

Source: https://habr.com/ru/post/1739031/


All Articles