Gunnar Peipman's ASP.NET blog

ASP.NET, C#, SharePoint, SQL Server and general software development topics.

Sponsors

News

 
 
 
DZone MVB

Links

Social

WCF and Unit Tests

Good practices demand tests for every new thing you have been able to get running. Otherwise our TDD chief is glum and moody during smoke breaks. So, to maintain the ever cheerful and busy climate in our office, this posting is going to discuss testing.

After installing WCF and getting it to work I also installed everything required for unit tests. It means I installed NUnit and TestDriven.Net and added a tests project to the project mentioned in the previous posting discussing WCF. I created an ordinary DLL library project for the tests, so it could be used with versions of Visual Studio that do not have built-in tests.

To use NUnit with a testing project you have to add a reference to nunit.framework.dll located under Program Files in the NUnit bin directory. This completes all preparations and we can continue with the tests.

New Methods for the Service

To have more things to test I added a couple of new methods to the service. Nothing complicated, just subtraction, multiplication and division, to cover all the four basic operations. Thus, we have to change the service contract and service class. The changes are as follows.


[ServiceContract()]
public interface IMathService
{
    [OperationContract]
    double Add(double x, double y);
    [OperationContract]
    double Subtract(double x, double y);
    [OperationContract]
    double Divide(double x, double y);
    [OperationContract]
    double Multiply(double x, double y);
} public class MathService : IMathService
{
    public double Add(double x, double y)
    {
        return x + y;
    }
    public double Subtract(double x, double y)
    {
        return x - y;
    }
    public double Multiply(double x, double y)
    {
        return x * y;
    }
    public double Divide(double x, double y)
    {
        return x / y;
    }
}

Unit Tests

For testing I created a class named MathServiceTest. We also have to add a Service Reference to the project and provide it with the URL to the MathService service. When the service is in place we can continue with the tests class.

To prevent creating and closing the service connection at every step we will connect to the service at the beginning of testing and disconnect after completing the tests.


using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
using NUnit.Framework;
using WCFTestTests.gamma; namespace WCFTestTests
{
    [TestFixture]
    public class MathServiceTest
    {
        private MathServiceClient client;
       
        [TestFixtureSetUp]
        public void Initialize()
        {
            this.client = new MathServiceClient();
            this.client.Open();
        }         [TestFixtureTearDown]
        public void TearDown()
        {
            if (this.client.State != CommunicationState.Closed)
                this.client.Close();
        }
    }
}

Next, we will add testing methods for all methods of the service.


using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Text;
using NUnit.Framework;
using WCFTestTests.gamma; namespace WCFTestTests
{
    [TestFixture]
    public class MathServiceTest
    {
        private MathServiceClient client;
       
        [TestFixtureSetUp]
        public void Initialize()
        {
            this.client = new MathServiceClient();
            this.client.Open();
        }         [TestFixtureTearDown]
        public void TearDown()
        {
            if (this.client.State != CommunicationState.Closed)
                this.client.Close();
        }         [Test]
        public void AddTest()
        {
            Assert.AreEqual(5, client.Add(2, 3));
        }         [Test]
        public void SubtractTest()
        {
            Assert.AreEqual(3, client.Subtract(8, 5));
        }         [Test]
        public void MultiplyTest()
        {
            Assert.AreEqual(12, client.Multiply(2, 6));
        }         [Test]
        public void DivideTest()
        {
            Assert.AreEqual(4, client.Divide(12, 3));
        }
    }
}

Let's start the NUnit GUI and run the test.


Press the right mouse button on the tests project, select Test With from the menu
and then NUnit from the submenu. The NUnit GUI opens.


NUnit GUI displays all classes containing tests, and tests included in the classes.
Tests can be run within a specific class, if required.


It seems I got lucky – all tests have succeeded!

If nothing went wrong all tests are displayed in green. It means we can safely say the service code works correctly. It went well with me this time, I hope you are as lucky or even luckier than I.

Coverage Test

At first, I didn't want to touch the Coverage Test at this time. When I started it, however, I noticed something that should be mentioned here, to widen the reader's horizons.

Let's start the coverage test. It's located in the same menu as the NUnit GUI. TestDriven.Net comes with NCover that enables us to run coverage tests. TestDriven.Net completes the coverage test automatically. You only have to select the appropriate item from the menu, and the results are displayed in a window.


Coverage test failed – code exists that is never run for our project,
unless we change the code.

As we can see the coverage test fails. Methods exist that are never used. These methods have been generated by the service's proxy generator and they are the four overloads of the proxy constructor.

If required, we can remove these constructors from the service's proxy, but refreshing the service causes these constructors to be automatically regenerated. If anybody knows how to prevent it, a comment would be welcome.

Summary

To sum it up, I can say that testing WCF services is not complicated as long as the services are simple. The development environment with all necessary tools can be created quickly and one can begin working almost at once. In addition to Unit Tests testDriven.Net also provides our development environment with Coverage Tests.

As I am dealing with a more complicated SOAP project at the moment, I am quietly contemplating the most effective way of testing the SOAP layer architecture after getting it in place. Anyway, it will certainly give me material for a couple of longer postings.


kick it on DotNetKicks.com vote it on WebDevVote.com pimp it Progg it Shout it

Comments

tommyk said:

I think its best to move your WCF client class and interface to a seperate project so you can test those without having to host them in WCF.  Then you can write a test to make sure you can correctly connect to the WCF and not test your methods through the generated code of the service client.

# January 13, 2009 2:16 PM

DigiMortal said:

Thank you for your feedback tommyk! :)

# January 13, 2009 8:13 PM

DotNetBurner - Web Services said:

DotNetBurner - burning hot .net content

# June 21, 2009 3:01 AM

PimpThisBlog.com said:

Thank you for submitting this cool story - Trackback from PimpThisBlog.com

# June 21, 2009 3:02 AM

DotNetKicks.com said:

You've been kicked (a good thing) - Trackback from DotNetKicks.com

# June 21, 2009 3:03 AM

WebDevVote.com said:

You are voted (great) - Trackback from WebDevVote.com

# June 21, 2009 3:06 AM

progg.ru said:

Thank you for submitting this cool story - Trackback from progg.ru

# June 21, 2009 3:07 AM

sam holder said:

@tommyk, whilst what you say is true, I believe there is some good value in having this kind of test. Testing the service class in isolation is better for proving the functionality, but does nothing to check that the values returned by your method can be serialized (and deserialized) by WCF, or to check that you have not got issues with type which your service is returning not being declared as KnownTypes in the service contracts etc etc.

So I would have the tests as you suggested, but I would also have WCF based tests to test that each type was being serialized/deserialized correctly

# June 15, 2011 3:44 AM