views:

382

answers:

2

Does anyone have an implementation lying around of an auto-mock container using Rhino Mocks and NInject?

+2  A: 

There is a RhonoMocks integration available.

Ian Davis
+2  A: 

OK I built one myself using the Moq integration as a starting point. It is very simple. You need these 3 classes:

public class AutoMockingKernel : StandardKernel
{
 private readonly IMockProvider _mockProvider;

 public void Reset()
 {
  Components.Get<ICache>().Clear();
 }

 protected override bool HandleMissingBinding(Type service)
 {
  var isSelfBindable = TypeIsSelfBindable(service);

  var binding = new Binding(service)
  {
   ProviderCallback = isSelfBindable
                       ? StandardProvider.GetCreationCallback(service)
                       : _mockProvider.GetCreationCallback(),
   IsImplicit = true
  };

  if (!isSelfBindable)
   binding.ScopeCallback = ctx => null;

  AddBinding(binding);

  return true;
 }

 public AutoMockingKernel(IMockProvider mockProvider, INinjectSettings settings, params INinjectModule[] modules)
  : base(settings, modules)
 {
  _mockProvider = mockProvider;
 }

 public AutoMockingKernel(IMockProvider mockProvider, params INinjectModule[] modules)
  : base(modules)
 {
  _mockProvider = mockProvider;
 }
}

internal class RhinoMockProvider : IProvider
{
 public Type Type { get; private set; }

 /// <summary>
 /// Initializes a new instance of the <see cref="RhinoMockProvider"/> class.
 /// </summary>
 public RhinoMockProvider(Type type)
 {
  Type = type;
 }

 public object Create(IContext context)
 {
  return MockRepository.GenerateMock(Type, Type.EmptyTypes);
 }
}

public class RhinoAutoMockProvider : IMockProvider
{
 public Func<IContext, IProvider> GetCreationCallback()
 {
  return ctx => new RhinoMockProvider(ctx.Request.Service);
 }
}

You can then create an auto-mocking kernel in your unit test like this:

[Test]
public void Test()
{
    var kernel = new AutoMockingKernel(new RhinoAutoMockProvider());
    ... etc
}
cbp
As a matter of interest, how do you manage triggering of Reset, in [Teardown] ?
Ruben Bartelink
I use a base class for all my test fixtures which calls Reset during teardown. I also use a static kernel container. Definitely not ideal, but I find this sort of stuff never is.
cbp