AutoMockingContainer and mock used in the constructor

I use a custom version of AutoMockingContainer based on the class used in this blog. The standard approach does not work for object that depends on some interface in the constructor, but actually uses that interface in the constructor and you need to set expectation on it.

Basically you need a way to intercept the generation of mock and configure before the constructor of the dependant object is created. This is achieved with a simple trick, first of all the AutoMockingContainer implemnts a specific interface

1
2
3
4
5
6
public interface IAutoMockingRepository : IWindsorContainer
{
MockingStrategy GetStrategyFor(DependencyModel model);
void AddStrategy(Type serviceType, MockingStrategy strategy);
void OnMockCreated(Object mock, String dependencyName);
}

The OnMockCreated is called by the ISubDependencyResolver object when the strategy requires to create a new mock with Rhino.mocks and the AutoMockingContainer is able to use this data to make possible to intercept mock creation.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
public void OnMockCreated(Object mock, String dependencyName)
{
if (!_mocks.ContainsKey(mock.GetType()))
{
_mocks.Add(mock.GetType(), new List<object>());
}
_mocks[mock.GetType()].Add(mock);
EventHandler<MockCreatedEventArgs> temp = MockCreated;
if (temp != null)
{
temp(this, new MockCreatedEventArgs(mock, dependencyName));
}
}

The container simply uses a Dictionary<Type, List<Object>> to keep track of object creation subdivided by type, but for each created mock he also raise an event with the mock and the dependency name. Now I have a LoginViewModel that depends on a ICustomerService with a customerService constructor parameters, and uses it in the constructor to query a list of customers. Here is the method that configures the AutoMockingContainer to make the test works.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
private void ConfigureAutoMockForStandardViewModel(AutoMockingContainer autoMockingContainer)
{
autoMockingContainer.Register(Component.For<LoginViewModel>());
autoMockingContainer.MockCreated += (sender, e) =>
{
if (e.DependencyName.Equals("CustomerService", StringComparison.InvariantCultureIgnoreCase) )
{
e.Get<ICustomerService>().Expect(s => s.GetAllClient()).Return(new List<Client>());
}
};
}

I scan creation of all mocks, and when mock for CustomerService dependency is created I simply setup an expectation. Simple and coincise.

Alk.