Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WCF Unit Test

How to unit test WCF services? Any 3rd Party tools available?

like image 427
user11039 Avatar asked Sep 30 '08 09:09

user11039


People also ask

Should we unit test constructors?

Is it worth testing that? Yes, it is often worth testing constructors with their own complex behavior.

Where can I find WCF test Client?

You can typically find the WCF Test Client (WcfTestClient.exe) in the following location: C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE - Community may be one of "Enterprise", "Professional" or "Community" depending on which level of Visual Studio is installed.

What are unit tests in C#?

A Unit Test is a code written by any programmer which test small pieces of functionality of big programs. Performing unit tests is always designed to be simple, A "UNIT" in this sense is the smallest component of the large code part that makes sense to test, mainly a method out of many methods of some class.


2 Answers

As aku says, if you're testing service methods (ie code behaviour) then you can unit test that directly and bypass the WCF infrastructure. Of course, if your code depends on WCF context classes (like OperationContext) then I suggest introducing wrappers much like ASP.NET MVC does for HttpContext.

For testing connectivity, it will depend on the type of endpoints you have configured. In some cases you can just self-host your WCF service inside the unit test (like you would with a WCF Windows Service) and test that.

However, you may need to spin up the ASP.NET Development Web Server or even IIS if you want to test WCF behaviour specific to those hosting environments (ie SSL, authentication methods). This gets tricky and can start making demands on the configuration of everyone's development machine and the build servers but is doable.

like image 200
Jason Stangroome Avatar answered Sep 17 '22 21:09

Jason Stangroome


I think the best approach is to separately test all concerns; test connectivity, client lib (proxies) and service method calls. Mocking and dependency injection is a good way to tests connectivity and service behaviour independently, but I doubt that it can get around middleware dependent endpoint tests.

You can create a service host in your test (self-hosted) and load you service. Once you set up your end points you can connect to it using your client proxies. This should work with simple HTTP and WSHTTP. In your Unit test you need to create a service reference to your service. Then you can create a host and wire your client with the test host together. I would try to avoid any tests using the "WCF Service Host" aka WcfSvcHost. (I mention this only because some people referred to the Visual Studio utils; which will work only if you only run tests from your IDE.)

If you need to check exotic authentication scenarios or endpoints which use special middleware you will need to create tests using the middleware. For simple sanity checks, etc using self-hosting is sufficient. Middleware dependent testing can cause test deployment issues if you are using a build server.

By middleware dependent endpoints I mean endpoints which are using for example MOMs (MSMQ, RabbitMQ, etc) or really exotic protocols, etc. Perhaps testing the client proxies with a self-hosted mock and testing the exotic endpoints separately is the way to go.

If you want to use dependency injection there are a few pretty sophisticated frameworks which provide “service abstraction” features which allow you to inject mock services, etc. I used Spring.NET with WCF a few times. Castle Windsor has WCF facilities as well.

Self-hosted test example:

    ServiceHost serviceHost = null;      try     {         var baseAddress = new Uri("http://localhost:8000/TestService");         serviceHost = new ServiceHost(typeof (ServiceClass), baseAddress);         Binding binding = new WSHttpBinding();         var address = new EndpointAddress("http://localhost:8000/TestService/MyService");         var endpoint = serviceHost             .AddServiceEndpoint(typeof (IServiceContract), binding, address.Uri);          var smb = new ServiceMetadataBehavior {HttpGetEnabled = true};         serviceHost.Description.Behaviors.Add(smb);          using (var client = new ProxyClient(endpoint.Name, endpoint.Address))         {             endpoint.Name = client.Endpoint.Name;              serviceHost.Open();              // ... magic happens          }          serviceHost.Close();     }     catch (Exception ex)     {         // ... tests     }     finally     {         if (serviceHost != null)         {             ((IDisposable) serviceHost).Dispose();         }     } 

I would like to point out that functional testing tools are not the same as unit testing tools. Unit testing should be about breaking down your test into a bunch of independent tests while functional testing is mostly about testing workflows end to end.

like image 45
Jeno Laszlo Avatar answered Sep 19 '22 21:09

Jeno Laszlo