Set up a mock object
SpecsFor includes an auto-mocking container that will automatically create mock objects for you using the excellent Moq library. By default, mock objects have no behavior. Consider this (trivial) domain:
public class CarFactory
{
private readonly IEngineFactory _engineFactory;
public CarFactory(IEngineFactory engineFactory)
{
_engineFactory = engineFactory;
}
public Car BuildMuscleCar()
{
return new Car
{
Engine = _engineFactory.GetEngine("V8")
};
}
}
public class Car
{
public Engine Engine { get; set; }
}
public class Engine
{
public string Maker { get; set; }
public string Type { get; set; }
}
public interface IEngineFactory
{
Engine GetEngine(string engineType);
}
Now let's look at the specs for building a muscle car:
public class when_creating_a_muscle_car : SpecsFor<CarFactory>
{
private Car _car;
protected override void When()
{
_car = SUT.BuildMuscleCar();
}
[Test]
public void then_it_creates_a_car_with_an_engine()
{
_car.Engine.ShouldNotBeNull();
}
}
Our CarFactory will be given a mock object, and when our factory calls its GetEngine method, the mock will happily hand back... null!
To fix this, we need to configure our mock with some behavior. We can ask SpecsFor to give us the mock object for a type by calling the GetMockFor method. Typically, you would perform this sort of setup by overridding the Given method, like so:
public class when_creating_a_muscle_car : SpecsFor<CarFactory>
{
private Car _car;
protected override void Given()
{
GetMockFor<IEngineFactory>()
.Setup(x => x.GetEngine("V8"))
.Returns(new Engine());
}
//snip
}
Now the spec will pass!
You can also verify that a method was called on a mock, like so:
public class when_creating_a_muscle_car : SpecsFor<CarFactory>
{
//snip
[Test]
public void then_it_calls_the_engine_factory()
{
GetMockFor<IEngineFactory>()
.Verify(x => x.GetEngine("V8"));
}
}
For more information about mocking, check out SpecsFor and mocking!
Updated less than a minute ago