Stephen Patten
Stephen Patten

Reputation: 6363

How to Mock an Autofac Aggregate Service with Moq?

I'm on .NET 4.6.2 and using the following versions of the assemblies via Nuget:

Service

Autofac - 4.8.1

Autofac.Extras.AggregateService - 4.1.0

Autofac.Wcf - 4.1.0

Castle.Core - 4.3.1

Tests

Autofac.Extras.Moq - 4.3.0

Moq - 4.10.1

The setup I'm using for the host container is exactly like the "Getting Started" example from the Docs and you end up with a proxy generated from DynamicProxy, and this works well by eliminating the constructor overloads.

When it comes to unit testing the services that use this type of injection I seem to be stumbling on how to mock it out properly.

I've spent a few hours trying various approaches and none of them have panned out. Here's basically what I have:

public interface IMyAggregateService
{
    IFirstService FirstService { get; }
    ISecondService SecondService { get; }
    IThirdService ThirdService { get; }
    IFourthService FourthService { get; }
}

public class SomeController
{
    private readonly IMyAggregateService _aggregateService;

    public SomeController(IMyAggregateService aggregateService)
    {
        _aggregateService = aggregateService;
    }
}

using (var mock = AutoMock.GetLoose())
{
    //var depends = mock.Mock<IMyAggregateService>().SetupAllProperties(); //Not working 

    //depends.SetupProperty(p => p.IFirstService, ?? );
    //depends.SetupProperty(p => p.ISecondService, ?? );
    //depends.SetupProperty(p => p.IThirdService, ?? );
    //depends.SetupProperty(p => p.IFourthService, ?? );

    var sut = mock.Create<SomeController>();

    Action action = () => sut.SomeAction();

    action.Should().xxxx

}

So the first problem I had was that there are no setters on the IMyAggregateService so the SetupProperty method won't work. When I used SetupAllProperties, everything was null at run-time, so that won't work. I even pulled down the Autofac.Extras.AggregateService code and was checking out the Test project, but there's really nothing I can gleam from it that might help, except the AggregateServiceGenerator might be useful at some point.

So my questions is,

"How do I properly mock an aggregate service, and provide behaviors for it during unit testing?"

For extra credit I'd like to know also how to provide a specific implementation of any of the dependencies that are properties, like this:

using (var mock = AutoMock.GetLoose())
{
    mock.Provide<IFirstService>(this.MyImplProperty);

Upvotes: 1

Views: 878

Answers (1)

Paweł G&#243;rszczak
Paweł G&#243;rszczak

Reputation: 574

"How do I properly mock an aggregate service, and provide behaviors for it during unit testing?"

Try to do smth like this (it is not using automoq just a moq :))

var firstServiceImpl= new Mock<IFirstService>();
var secondServiceImp2= new Mock<ISecondService>();

var myAggregateServie= new Mock<IMyAggregateService>();

myAggregateServie.SetupGet(x => x.FirstService ).Returns(firstServiceImpl);
myAggregateServie.SetupGet(x => x.SecondService ).Returns(secondServiceImp2);
.
.
.

And then you can mock behaviours of your services, and verify calls, some pseudo code will look like this.

//Mock as above
//Mock service behavior
firstServiceImpl.Setup(m=>m.Method1()).Returns(1)

//test method of you controller, lets assume that the method1 of controller 
//is only calling firstService method named Method1()

var result = SampleController.Method1(); 

Assert.IsTrue( result == 1) 
firstService.Verify(m=>m.Method1(), Times.Once()). 

Upvotes: 3

Related Questions