Dependency Injection and Mocking a WCF Service

From times to times you get those basic questions that you feel are not worth asking, or should be understood by default. Well turns out as soon as you begin to explain the solution, you've lost yourself in the details.

One of those questions I was recently asked was about Mocking WCF Services for Unit Tests. Most of the times I work on C# Projects, the infrastructure is already setup, so you tend just to use the stuff provided by a fellow architect. Although the question seems narrowed down, it does involve some more aspects. One of them is to choose how to structure your code so it gets testable. That was a nice opportunity to test out Autofac, a fully featured Inversion of Control Container. As for the testing aspect I've chosen Moq, which is a very simplistic and yet powerful Mocking Library. So in order to provide a proper answer I've created a GitHub Repository depicting the whole story. It contains a DemoService which is a console application hosting a WCF Service, a DemoApp which consumes the Service and shows how to use the mentioned Libraries as well as a Unit Test project called DemoApp_Test.

Creating a simple WCF Service

Lets start with the service layer. The demonstrated service implements the following ITheService interface.

...

namespace DemoService
{
    [ServiceContract]
    public interface ITheService
    {
        [OperationContract]
        string RegisterPerson(Person p);
    }

    [DataContract]
    public class Person {
        [DataMember]
        public string FirstName { get; set; }
        [DataMember]
        public string LastName { get; set; }
    }
}

As we can see there is only one operation contract named RegisterPerson which takes a Person being a registered as a data contract and two data members first / lastname.

Next lets take a look at the service implementation.

...

namespace DemoService
{
    public class TheService : ITheService
    {
        public string RegisterPerson(Person p)
        {
            return string.Format("Successfully registered {0} {1}",
              p.FirstName, p.LastName);
        }
    }
}

Nothing too spectacular happens here, as the method just returns a string with the details of the registered person.

Setting up Autofac for Dependency Injection

OK so much for the service now its time to take a look at our demo application. We'll start with the file Program.cs. First we'll setup an Autofac container used for our dependency injection efforts. This is done by creating an instance of ContainerBuilder

namespace DemoApp
{
    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ContainerBuilder();

Now the way how most of the .NET dependency injection systems work, is to register a specific type, which is provided when a given interface is requested. All of this should be done as close as possible to the root of the application, thus our Main function. In below example you'll see that we register the concrete service implementation TheServiceClient — the WCF auto generated proxy — to be returned when ITheService is requested.

            builder.RegisterType<MyService.TheServiceClient>()
                .As<MyService.ITheService>();

The app puts all its massive logic into a class named Core. We do also register that one with our DI-Container. The difference here, compared to the previous example is that we're using builder.Register to register a concrete type vs. an interface abstraction. This method accepts lambda-expression as parameter, which defines how the specific class has to be instantiated. As you can see we do inject a IComponentContext, which I'll explain a bit later, and the mentioned service into Core`s constructor.

            builder.Register<Core>(b => 
                new Core(b.Resolve<IComponentContext>(),
                         b.Resolve<DemoApp.MyService.ITheService>()));

Over here we a similar thing with our very important business logic, which is excluded into its own class. What we additionally do here is to tell Autofac, to always return the same instance in the same instance scope.

            builder.Register<BusinessLogic.VeryImportantBusinessLogic>(b =>
                new VeryImportantBusinessLogic())
                   .InstancePerLifetimeScope();

After registering all of our types we can create the container instance using the builders Build method. After that lets use it to resolve an instance of Core and call its Init method and then wait for an user input to end the application.

            IContainer Container = builder.Build();

            Console.WriteLine(Container.Resolve<Core>().Init());

            Console.WriteLine("\nHit enter to exit ...");
            Console.Read();
        }
    }
}

V E R Y important Business Logic

Next lets take a quick look at the VeryImportantBusinessLogic which just provides a simple method GetVIP, returning an anonymous object with the first- and lastname of a Person.

...

namespace DemoApp.BusinessLogic
{
    public class VeryImportantBusinessLogic
    {
        public dynamic GetVIP()
        {
            return new {
                firstName = "Vildan",
                lastName = "Softic"
            };
        }
    }
}

Injecting the DI-Container

So much for setting up our application, lets now take a look at Core's implementation.
First we create the fields Service and Context which will hold the injected constructor instances. Speaking of that, you can see that the first parameter is the previously mentioned IComponentContext, which itself is the currently used Container for our scope. Now the next thing might not be the best design but was chosen to demonstrate, how you can resolve a dependency deeper in your code instead of having it injected to its constructor, which some would argue, defeats he purpose of IoT but at the same time reduces the number of necessary constructor parameters. We do resolve an instance of our important business logic and call its GetVIP method. The returned anonymous object is then passed on to GeneratePerson in order to return us an instance of Person, which we're passing to the service method RegisterPerson and return its result.

namespace DemoApp.BusinessLogic
{
    public class Core
    {
        IComponentContext context;

        public ITheService Service { get; set; }
        public Core(IComponentContext context, ITheService srv)
        {
            this.Service = srv;
            this.context = context;
        }

        public string Init()
        {
            var VIP = context.Resolve<VeryImportantBusinessLogic>()
                        .GetVIP();

            return this.Service
              .RegisterPerson(
                this.GeneratePerson(VIP.firstName, VIP.lastName)
              );
        }

        public Person GeneratePerson(string firstName, string lastName)
        {
            return new Person()
            {
                FirstName = firstName,
                LastName = lastName
            };
        }
    }
}

So far you've seen how to leverage Autofac for dependency injection and how to possibly structure an application to make the best use of it. In order to try this out just set both the DemoApp and DemoService as Startup Projects and run the solution.

Testing with Moq

Having setup the service and demo application, its time to see how we can use Autofac inside an unit test and mock the service with Moq.

When installing Moq and Autofac.Extras.Moq — the helper library for integrating Moq with Autofac — with Nuget, I got a version mismatch for Autofac. So in order to avoid that just simply manually install Autofac as well via Nuget.

After adding the necessary references Autofac, Autofac.Extras.Moq and Moq via NuGet, we can start writing our test. We setup our test by starting our environment under test conditions using AutoMock.GetLoose. What this does is essentially creating Mocks for every dependency registered and injecting those into constructors. This test is going to show that the method RegisterPerson is returning the proper result, yet not talking to the actual service. In order to do that, we're going to Mock the method. We start by mocking the service, so that every request to the ITheService interface gets the mocked version. Then we Setup a mock for the specific method. Note the declaration of how we'd like to accept the first parameter. After that we define what the expected return value is, in our case a simple string leveraging information from the provided Person parameter.
Last but not least we can now create a mocked instance of our Core class and run the Init method, which will then internally call the mocked service method.

[TestMethod]
public void Should_Return_Registered_Person()
{
    using (var mock = AutoMock.GetLoose())
    {
        mock.Mock<DemoApp.MyService.ITheService>()
            .Setup(srv => srv.RegisterPerson(
               It.IsAny<DemoApp.MyService.Person>()
             ))
            .Returns<DemoApp.MyService.Person>(p =>
                "[MOCK] Successfully registered " +
                 p.FirstName + " " + p.LastName);

        var sut = mock.Create<DemoApp.BusinessLogic.Core>();
        Assert.AreEqual("[MOCK] Successfully registered Vildan Softic",
          sut.Init());
    }
}

Conclusion

As you've seen the process to include AutoFac and Moq for dependency injection and service mocking, is not that hard and requires only a few configurations. The experience with using Autofac was pretty pleasant and their docs are full of good information. I was very happy that there is also a nice integration with Moq, which makes setting up unit tests very easy.

I hope you enjoyed reading about this great combo and am looking forward to reading your questions and/or feedback below in the comments.

photo credit: Laboratory via photopin (license)