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.
1 | ... |
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.
1 | ... |
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
1 | namespace DemoApp |
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.
1 | builder.RegisterType<MyService.TheServiceClient>() |
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.
1 | builder.Register<Core>(b => |
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.1
2
3builder.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.
1 | IContainer Container = builder.Build(); |
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.
1 | ... |
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.
1 | namespace DemoApp.BusinessLogic |
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
andAutofac.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.
1 | [ ] |
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)