How to Mock a WCF Service with Unity and Moq

by Larry Spencer Wednesday, June 1, 2011 6:32 AM

In today’s service-oriented architectures, unit testing is more challenging than ever. How do you isolate and test a service that depends on five other services?

One way is to mock those dependent services.  The example we’ll work through has three components:

  • WcfApp - A WCF application that can get data about customer preferences.  Specifically, we want to know each customer’s favorite item on a menu.
  • CouponGenerator - Generates coupons based on customers’ favorites. This assembly calls WcfApp to learn what each customer’s favorite is.
  • CouponGeneratorTests - The unit-test assembly for CouponGenerator.

MockWcf.sln

Our problem: We want to be able to test the CouponGenerator assembly without relying on the WcfApp.

The solution will be to use Moq to mock the WCF application, and the Unity dependency-injection framework to inject the mock.

Let’s work our way from the inside out, starting with the WCF application.

 

The WCF Service Application

 

The ICustomerPreferences service contract and its implementation couldn’t be simpler. 

using System.ServiceModel;

namespace WcfApp
{
    [ServiceContract]
    public interface ICustomerPreferences
    {
        /// <summary>
        /// Gets the customer's favorite item on the menu.
        /// </summary>
        /// <param name="customerId">The unique ID of the customer.</param>
        /// <returns>The customer's favorite.</returns>
        [OperationContract]
        string GetFavoriteMenuItem(int customerId);
    }
}
namespace WcfApp
{
    public class CustomerPreferences : ICustomerPreferences
    {
        /// <summary>
        /// Gets the customer's favorite item on the menu.
        /// </summary>
        /// <param name="customerId">The unique ID of the customer.</param>
        /// <returns>The customer's favorite.</returns>
        public string GetFavoriteMenuItem(int customerId)
        {
            return "Jumbo Burger";
        }
    }
}

 

The Coupon Generator

 

This is the assembly that depends on the WCF application, and that dependency is what we want to break.

The coupon generator contains a service reference generated by Visual Studio.  (In production I prefer to craft my own, using a library of goodies I’ve developed for the purpose, but Visual Studio’s service references are familiar to everyone so let’s go that route for now.)

The main class of interest, Coupon, calls the WCF service in the process of creating a simple, text-based coupon.  However, it does not use the generated Service Reference directly.  Instead, it uses Unity to point to either the real WCF service or the mock we’ll discuss in a moment.

Normally, the code would go like this:

var proxy = new CustomerPreferencesClient();
var fave = proxy.GetFavoriteMenuItem(CustomerId);

The Unity dependency-injection framework allows us to specify in a configuration file what class we want to instantiate for an ICustomerPreferences contract.  It takes just one additional line of code. 

var unity = new UnityContainer().LoadConfiguration();
var proxy = unity.Resolve<ICustomerPreferences>();
var fave = proxy.GetFavoriteMenuItem(CustomerId);

In our case, we want to inject a CustomerPreferencesMock, which is in our unit testing assembly.  More on that in a moment; first, here is the complete listing for Coupon.cs.

using System;
using System.Collections.Generic;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

using CouponGenerator.ServiceReference1;

namespace CouponGenerator
{
    public class Coupon
    {
        public int CustomerId { get; set; }

        public Coupon(int customerId)
        {
            CustomerId = customerId;
        }

        public string[] AsText()
        {
            // Without Unity's dependency injection:
            //var proxy = new CustomerPreferencesClient();
            
            // With dependency injection:
            var unity = new UnityContainer().LoadConfiguration();
            var proxy = unity.Resolve<ICustomerPreferences>();
            try
            {
                var fave = proxy.GetFavoriteMenuItem(CustomerId);

                var strings = new List<string>();
                strings.Add("------------------------------------------------------------");
                strings.Add("COUPON");
                strings.Add(String.Format("You get 10% off your next {0} order!", fave));
                strings.Add("------------------------------------------------------------");
                return strings.ToArray();
            }
            finally
            {
                if (proxy is IDisposable)
                    (proxy as IDisposable).Dispose();
            }
        }
    }
}

 

The Unit Testing Assembly

 

Our first unit test looks like this.  We instantiate a Coupon and make sure it has the right text.

[TestMethod]
public void AsText_GoodCustomerId_DefaultMock()
{
    int customerId = 100;

    var coupon = new Coupon(customerId);

    var expected = new string[]
    {
        "------------------------------------------------------------",
        "COUPON",
        "You get 10% off your next Fish and Chips order!",
        "------------------------------------------------------------",
    };
    var actual = coupon.AsText();

    Assert.IsTrue(expected.SequenceEqual(actual));
}

Here’s the magic.  Because we coded the Coupon class to use Unity, the unit test’s app.config can inject a mock class:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">

    <assembly  name="CouponGenerator"/>
    <assembly  name="CouponGeneratorTests"/>

    <container>
      <register type="CouponGenerator.ServiceReference1.ICustomerPreferences" 
                mapTo="CouponGeneratorTests.CustomerPreferencesMock" />
    </container>
  </unity>
</configuration>

What’s in the mock?  Notice the following features in the next listing.

  • It inherits from ICustomerPreferences.  This must be the case if we are going to use Unity to inject it as our stand-in for the real implementation of ICustomerPreferences.
  • It has a static Mock property which gets initialized on first use.
  • Initialize() sets up a sort of fake database by telling the mock to return “Fish and Chips” for one customer and “Pepperoni Pizza” for another.
  • The implementation of ICustomerService delegates to the corresponding method in the mock.
using Moq;
using CouponGenerator.ServiceReference1;

namespace CouponGeneratorTests
{
    public class CustomerPreferencesMock : ICustomerPreferences
    {
        #region Properties
        static Mock<ICustomerPreferences> _mock = null;
        /// <summary>
        /// Static property to access the Mock of ICustomerPreferences
        /// </summary>
        static public Mock<ICustomerPreferences> Mock
        {
            get
            {
                if (_mock == null)
                    Initialize();
                return _mock;
            }
        }
        #endregion

        #region Initialize
        /// <summary>
        /// Reset the Mock to the default fake values.
        /// </summary>
        static public void Initialize()
        {
            _mock = new Mock<ICustomerPreferences>();
            _mock
                .Setup(custPrefs => custPrefs.GetFavoriteMenuItem(It.Is<int>(id => id == 100)))
                .Returns("Fish and Chips");
            _mock
                .Setup(custPrefs => custPrefs.GetFavoriteMenuItem(It.Is<int>(id => id == 101)))
                .Returns("Pepperoni Pizza");
        }
        #endregion

        #region ICustomerPreferences Implementation
        public string GetFavoriteMenuItem(int customerId)
        {
            return Mock.Object.GetFavoriteMenuItem(customerId);
        }
        #endregion
    }
}

Because Mock is exposed as a static property, our unit tests can modify the mock.  Here we have changed customer 100’s preference from Fish and Chips to Steak Sandwich.

[TestMethod]
public void AsText_GoodCustomerId_ModifiedMock()
{
    int customerId = 100;

    string fave = "Steak Sandwich";
    CustomerPreferencesMock.Mock
        .Setup(custPrefs => custPrefs.GetFavoriteMenuItem(It.Is<int>(id => id==customerId)))
        .Returns(fave);

    var coupon = new Coupon(customerId);

    var expected = new string[]
    {
        "------------------------------------------------------------",
        "COUPON",
        String.Format("You get 10% off your next {0} order!",fave),
        "------------------------------------------------------------",
    };
    var actual = coupon.AsText();

    Assert.IsTrue(expected.SequenceEqual(actual));
}

 

Running the Tests

 

When you run the tests, you will see that the WCF service does not even start.  You could actually delete it from your drive and the tests would work.

Of course, you’d still want integration tests to make sure the WCF aspects of your system were working, but our focus here is on the unit tests.

 

Benefits

 

This decoupling has several benefits.

  • You’ll be more productive because your unit tests will be much faster.
  • You’ll also be more likely to write lots of unit tests if you don’t have to pay a penalty every time they run.
  • Your test environment will be much easier to set up, since you’ll have fewer environmental dependencies.  For example, you won’t care if your WCF service uses a database because you’re not actually running the service.

 

Configuring for Production

 

In production, all we have to do is use a config file that names the real client instead of the mock. 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">

    <assembly  name="CouponGenerator"/>
    <assembly  name="CouponGeneratorTests"/>

    <container>
      <register type="CouponGenerator.ServiceReference1.ICustomerPreferences" 
                mapTo="CouponGenerator.ServiceReference1.CustomerPreferencesClientUnityFriendly" />
    </container>
  </unity>
</configuration>

However, there’s one small annoyance.  You may have noticed the mapTo name: CustomerPreferencesClientUnityFriendly. Here's what's going on with that. Unity likes to use the constructor with the most parameters.  In the case of the CustomerPreferencesClient that Visual Studio generated, there are three that fit this description, each with two parameters.  Unity will be confused because it doesn't know which of the three to use.  There are various ways to help Unity out of this confusion.  The one I’ve chosen is to create a separate, Unity-friendly client that inherits from the one Visual Studio generated.  The Unity-friendly client has only a default constructor.  Problem solved. 

namespace CouponGenerator.ServiceReference1
{
    /// <summary>
    /// Unity-friendly extension of the CustomerPreferencesClient.
    /// It's Unity-friendly because there's no ambiguity among constructors.
    /// </summary>
    public class CustomerPreferencesClientUnityFriendly : CustomerPreferencesClient
    {
        public CustomerPreferencesClientUnityFriendly()
        { }
    }
}

 

Summary

 

We have seen how to create a mocked version of a WCF service, and how to inject it into your unit tests with Unity.  The mocked version can contain fake data, but you can also override the mock in individual tests.

The benefits are faster tests and fewer environmental dependencies.

Tags: , , ,

All

Comments (2) -

12/16/2011 3:38:33 PM #

This is a great example about breaking dependencies with WCF, my 2 cents here will be that you can set the default constructor for the Service reference in the config file like this:

<register type="CouponGenerator.ServiceReference1.ICustomerPreferences"
                mapTo="CouponGenerator.ServiceReference1.CustomerPreferencesClient" >
        <constructor>
        </constructor>
      </register>

In this way we will use the empty constructor. Again great code I just thought this small setting can help to reduce the creation of a couple extra classes.

Valentino Marin United States

2/18/2013 11:00:18 AM #

If like me you got the error on the mock file supplied within the config file, please see my question here for detailed problem + solution:

stackoverflow.com/.../type-name-could-not-be-resolved-please-check-config-file

Neeta United Kingdom

Pingbacks and trackbacks (1)+

Add comment

About the Author

Larry Spencer

Larry Spencer develops software with the Microsoft .NET Framework for ScerIS, a document-management company in Sudbury, MA.

 
Favor Composition Over Inheritance

Favor Composition Over Inheritance

by Larry Spencer Sunday, July 1, 2012 11:53 AM

 

In the last two posts, I considered relatively exotic ways to build up a class: .NET’s partial class feature and extension methods. This time, I’ll compare two ways to make classes relate to each other: inheritance and composition, colloquially known as is-a and has-a relationships.

The programming literature builds a solid case for favoring composition over inheritance. The best-selling book, Design Patterns: Elements of Reusable Object-Oriented Software by the “Gang of Four” makes this point, as does Robert Martin’s well-known paper, Design Principles and Design Patterns.

Nevertheless, time pressures often push developers toward the quickest way to make the services of one class available through another. That would be inheritance. There are no pass-through methods to write, and very little can go immediately wrong. It should come as no surprise that one developer described a recent adventure in class design thus: “So I looked around for something to inherit from…”

But you’re one of the lucky few. You’re reading this blog, so you must have plenty of time on your hands – certainly time enough to consider my official list of…

Qualifiers for Inheritance

Only use inheritance if all of the following are true. Otherwise, use composition.

  • The classes must have a true, semantic is-a relationship. Otherwise, you’re lying. Chances are good that the other programmers on your team are straight arrows, and lies will confuse them.
  • You can think of no possible reason why you might want to mock the base type in unit testing. Composition allows you to inject such a mock in the derived type’s constructor. That can be very handy.
  • You are willing to forego the possibility of changing the base type a run-time. Composition and an Inversion-of-Control container are a powerful combination.
  • You need to use all the interfaces that the base type implements. If not, consider just inheriting from the interface(s) you need. (This is a corollary of the Interface Segregation Principle.) You can then instantiate or inject a member of what would have been the base type to implement those interfaces. 
  • Either you will always need the services of the base type, or constructing it costs nearly nothing. Otherwise, you might want to delay its construction until it’s actually needed. That’s impossible with inheritance, but easy with composition.

That’s my list. If you have anything to add, please leave a comment!

Tags: , , , ,

All | Composibility | Dependency Injection

Add comment

About the Author

Larry Spencer

Larry Spencer develops software with the Microsoft .NET Framework for ScerIS, a document-management company in Sudbury, MA.