Saturday, November 19, 2011

Using MSpec.Fakes–Part 2

Next example I’d like to show is how to force a method to return a specific value:

public class example_when_told_to : WithFakes
{
    private static int result;
    private static IHelper sut;

    private Establish context = () =>
        {
            sut = An<IHelper>();
            sut.WhenToldTo(s => s.OK(Arg<int>.Is.Anything)).Return(4567);
        };

    private Because of = () => result = sut.OK(1);

    private It should_be_4567 = () => result.ShouldEqual(4567);
}

Here I use ‘WhenToldTo()’ in order to control the return value of ‘OK()’. I could also do this:

public class example_when_told_to : WithFakes
{
    private static int result;
    private static IHelper sut;

    private Establish context = () =>
        {
            sut = An<IHelper>();
            sut.WhenToldTo(s => s.OK(23)).Return(4567);
        };

    private Because of = () => result = sut.OK(23);

    private It should_be_4567 = () => result.ShouldEqual(4567);
}

So when ‘OK()’ is called with a specific argument, in this case 23, I want to return the value 4567. OK, so let’s have a look at using the ‘WithSubject’ parent class. First, we need the code for the salary calculator which Helper is using:

public interface ISalaryCalculator
{
    double CalculateSalary(double baseSalary, double bonus);

    int GetValue();
}

public class SalaryCalculator : ISalaryCalculator
{
    public double CalculateSalary(double baseSalary, double bonus)
    {
        return baseSalary + bonus;
    }

    public int GetValue()
    {
        return 34;
    }
}

Now here is the example test class we’ll be referencing:

public class example_using_WithSubject_1 : WithSubject<Helper>
{
    private static int result;

    private Establish context = () => The<ISalaryCalculator>().WhenToldTo(x => x.GetValue()).Return(1);

    private Because of = () => result = Subject.OK(1);

    private It should_be_1 = () => result.ShouldEqual(1);
}

We’re using WithSubject and passing it the type of Helper. What this give us is a .Subject property that we can use to access the SUT (i.e. the instance of Helper). The other cool thing is that since Helper requires an implementation of ISalaryCalculator in it’s constructor, an instance of ISalaryCalculator will be created for us. Not only that, but we can control the behaviour of the ISalaryCalculator instance via the ‘The<>’ method.

In the above example I’m stating that when ISalaryCalculator.GetValue() is called, it should return 1. We can also verify calls against the ISalaryCalculator like this:

public class example_using_WithSubject_2 : WithSubject<Helper>
{
    private static int result;

    private Because of = () => result = Subject.OK(1);

    private It should_be_1 = () => The<ISalaryCalculator>().WasToldTo(x => x.GetValue());
}

That’s all for now. I might write a bit more about using Stubs in your MSpec.Fakes tests for part 3.