Thursday, January 08, 2009

Integration testing for WCF with MSTest

As part of my research on WCF (with an eye on upgrading our existing web services) I started investigating how to create automated integration tests for WCF services. With our current services we write our integration tests in MSTest. To run the tests we all also need to either have the services set-up in IIS or or spin them up in an instance of Visual Studio. This makes running the tests fiddly and also complicates if we want to automate them as part of the build process.

With WCF we now can self-host a service which gives us some new options in regard to testing.
Howard van Rooijen in his blog offered a solution (Configuring WCF services for Unit Testing) which created an internal ServiceHost wrapper class for a new instance of the service host for testing. Though this solution worked there was a couple of areas where I thought it could be improved.

What I have done is:
a) remove the need for creating and maintaining a configuration file
b) move the whole thing into a seperate generic class ( called ServiceManager) which the contract and service as type parameters.
c) simplifying the the set-up process so it is more "set and forget" for a set of tests
d) incorporated the ChannelFactory creation into the class.

The code for this can be downloaded from the following link: Service manager for WCF tests.

To use the ServiceManager class we first create an instance of it:


[TestClass]

public class WebServiceIntegrationTests

{

static string baseAddress = @"http://localhost:8000/WebServiceTests";

static ServiceManager<IPeopleService, PeopleServiceType> serviceManager =

new ServiceManager<IPeopleService, PeopleServiceType>(baseAddress);


Having do that we then add the following code to the class initialise and cleanup methods:

[ClassInitialize()]

public static void ClassInitialize(TestContext testContext)

{

serviceManager.StartService();

}

[ClassCleanup()]

public static void ClassCleanup()

{

serviceManager.StopService();

}


With the service of the service host running all we need to do is write our testing using an instance of the ChannelFactory class:


[TestMethod]

public void GetNewPersonFromService()

{

string firstName = "Bob";

string lastName = "Builder";

int age = 35;

RelationshipType relation = RelationshipType.Business;

using (var factory = serviceManager.GetChannelFactory())

{

IPeopleService client = factory.CreateChannel();

Person person = client.GetNewPerson(firstName, lastName, age, relation);

Assert.AreEqual<string>(firstName, person.FirstName);

Assert.AreEqual<string>(lastName, person.LastName);

Assert.AreEqual<int>(age, person.Age);

Assert.AreEqual<RelationshipType>(relation, person.Relationship);

}

}


The key thing with this solution is that it is very easy to set-up and we don't have to worry about configuration settings for the services since it is all done programmatically. This means that setting and maintaining the tests is a lot easier which is always a good thing.




No comments: