Testing WCF Service Apps (Part 1 of 4)

Previous posts: Part 0 of 4: Introduction

Shout it kick it on DotNetKicks.com

Testing the Service

Of the four posts, testing the service is by far the easiest.

One of the most beautiful things about the WCF framework is the way it was designed to be more testable than ASPX services.  When you design your WCF interface, you are mostly just designing an interface with the WCF ServiceContract attributes.  The WCF framework uses your interface to determine the actual contract and transport mechanism so you don’t have to. 

This is the key to testing WCF services:  YOU DON’T HAVE TO WORRY ABOUT THE WCF FRAMEWORK.  This means that you can simply instantiate your service directly and start calling public methods on it.  You never need to worry about hitting the service through the transport layer.  You can focus on what is important: your code.

Recipe Box Service Interface

This is the interface that my WCF service publishes:

[ServiceContract]
public interface IRecipeBoxService
{
    [OperationContract]
    RecipeData[] AllRecipes();

    [OperationContract]
    void SaveRecipe(RecipeData recipe);

    [OperationContract]
    void DeleteRecipe(int id);

    [OperationContract]
    IngredientData[] AllIngredients();

    [OperationContract]
    void SaveIngredient(IngredientData ingredient);

    [OperationContract]
    IngredientData[] FindIngredients(string nameIsLike);

    [OperationContract]
    void DeleteIngredient(int id);
}

The Tests

The actual implementation is named RecipeBoxService, and that is the class I am interested in testing.   A test might look something like this:

[Test]
public void Test_Get_All_Recipes_Returns_SingleRecipe()
{
    PopulateDatabase(new Recipe("AAA", "BBB", "CCC"));

    var recipeBoxService = new RecipeBoxService();
    var recipes = recipeBoxService.AllRecipes();

    Assert.That(recipes.Length, Is.EqualTo(1));
    Assert.That(recipes[0].Title, Is.EqualTo("AAA"));
    Assert.That(recipes[0].Description, Is.EqualTo("BBB"));
    Assert.That(recipes[0].Author, Is.EqualTo("CCC"));
}

It is that simple.  YOU SHOULD NEVER NEED TO CREATE A SERVICE REFERENCE IN YOUR TEST PROJECT.  Forget about WCF and test your service logic directly.

Abstracting the back end

Note: I am using a database abstraction product called Castle Active Record in my service which gives me a lot of great features.  From a testing perspective, the most important feature is that you can swap out the actual database for a more testable back end.  Good unit tests (usually) do not rely on external databases, external services, file systems or any other environment-specific requirements.  In my approach, I am using an in-memory, temporal database that only lives as long as the test does.  Please see my post on mocking out the database with ActiveRecord or more information on this.

Next time

I will talk about how you test the client without connecting to the service. (Part 2 or 4)

Leave a Reply