共用方式為


Unit Testing WCF Services

A few years ago, when ASP.NET web services were the only (or at least most common) implementation of web services on the Microsoft platform, you couldn't really unit test services. Obviously, since you had programmatic access (via a proxy class) to the service, you could write tests against the service using unit testing tools, but in my terminology, these tests are integration tests, not unit tests.

This lead to the guiding principle that a service should just be a remote façade for a service library; that service library could then be subjected to unit testing, and the service itself would just delegate all messages to the library (and thus contain so little code that it didn't require testing in itself).

With WCF, this is no longer the case, since WCF services are just libraries. This means that you can just add a reference to your service from a test project, and start writing tests against the library like this:

 [TestMethod]
 public void DoStuffInProcess()
 {
     MyService ms = new MyService();
     string result = ms.DoStuff("Ploeh");
     Assert.AreEqual<string>("Ploeh", result);
 }

However, to be able to do this, you must ensure that the service library doesn't use any WCF-specific code. As soon as you begin to use OperationContext.Current in your service, your unit tests are very likely to fail, since this static property will be null when not hosted by WCF.

Although this may feel like too much of a constraint, this is often a beneficial approach, since it helps ensure separation of concerns. Service operations should implement business logic, not transport logic or other, similar kinds of unrelated activity.

While that may be true, you will often still need to know something about the context of the operation, such as the identity of the caller. In many cases, such requirements can still be addressed while maintaining separation of concerns, since WCF allows you to configure message interceptors, authorization managers, etc.

Even if you are able obtain perfect separation of concerns, you may still want to test your authorization managers or other extensions, and that will often require hosting by WCF. In such cases, integration testing is the proper approach, but that doesn't mean that you shouldn't unit test as far as you can get.

In future articles, I will write about integration testing of WCF services. Update: My first WCF integration testing post is now online.

Comments

  • Anonymous
    December 03, 2006
    A colleague of mine recently wrote about seperation of concerns in relation to unit testing WCF services.

  • Anonymous
    December 04, 2006
    Great post! In my organization we've been trying to figure out a way to unit test our services and this is exactly the scenario that we've discussed.  However, we DO use OperationContext.Current in our services in order to get identity info, and so we're currently developing our unit tests around the client proxy. I'll be looking forward to your future posts about how to do the integration testing -- I hope there's a way to latch into the WCF pipeline and have OperationContext.Current provide identity information without having to have the service be executing under WCF.

  • Anonymous
    December 04, 2006
    In my previous post about unit testing WCF services , I hinted at the need to perform integration testing

  • Anonymous
    December 04, 2006
    Hi Sean Glad you liked the post :) As you may have noticed, I've just posted my next article about WCF integration testing, although this particular article doesn't address the separation of concerns between service operations and, say, authorization. I may get to this subject in a later post, but until then, take a look at ServiceAuthorizationManager. Deriving from this class basically lets you write your authorization logic in a central place so you don't need to access OperationContext.Current in a lot of other places. In a custom authorization manager, you can, after authorizing the caller, extract all the necessary information about the caller and create an IPrincipal instance and place it on Thread.CurrentPrincipal.

  • Anonymous
    January 04, 2007
    In my post about integration testing of WCF services , I briefly touched on the topic of authorization

  • Anonymous
    December 11, 2007
    I also feel this post is well written and very nicely explained.  Looking at it like that makes me wonder why I had questioned the method in the first place.

  • Anonymous
    December 11, 2007
    Hi Brad Thanks - glad you liked it :)

  • Anonymous
    June 25, 2008
    More than a year ago, I wrote my first post on unit testing WCF services . One of my points back then

  • Anonymous
    January 12, 2009
    ADO.NET Data Services enables you to expose data (including, but not limited to, relational data) as

  • Anonymous
    April 07, 2009
    A tool like WCFStorm might be useful in this case. It can create test cases  and invoke WCF methods so in a way you are doing Unit and Integration testing at the same time. http://geekswithblogs.net/Erik/archive/2009/04/02/130664.aspx

  • Anonymous
    April 08, 2009
    Hi Alex Thanks for sharing :)

  • Anonymous
    July 28, 2010
    Can anyone suggest what are the new techniques we can apply in the Unit testing for expecting more good results? Hope i will get the response soon....

  • Anonymous
    July 28, 2010
    Are you asking about unit testing in general? If so, Stack Overflow might be a more appropriate forum: http://stackoverflow.com/

  • Anonymous
    December 27, 2010
    Its good approach for API kind of service, not for service base applications, at least not classic silver-light applications, because you always need the context (user context, application state,...).  

  • Anonymous
    January 02, 2014
    that was helpful thanks!