Test Driven Development is a great thing in software development as it makes it possible to verify your code very easily during development and when you have to make changes. However, it is not always easy to write solid unit tests when external influences are involved.
For example, in case of Web Services you might want to avoid the actual Web Service calls in your unit tests for reasons like availability, performance, predictability, ... of the Web Service. In my case I had to avoid the Web Services because I couldn't rely on the information they returned (the content of the underlying ERP database was out of my control).
To solve this problem for the unit tests and get a predictable response that can be tested there are basically two solutions:
- Create a dummy Web Service that replaces the actual Web Service;
- Replace the proxy of Web Service in the project by a dummy proxy.
In my project I choose for the latter on, based on a technique that is described in a blog post by David Waddleton. The trick that makes this technique possible and fairly easy is that the generated proxy is a partial class (.NET 2.0). This makes it possible to define an interface on the generated proxy (without changing it) by writing your own partial class. The service consumer can now communicate with the Web Service using the interface instead of directly to the Web Service. At this point you are free to replace the Web Service implementation for a mock object during the unit tests using some form of dependency injection.
Note: In the picture above the class MyService is displayed as two classes for clarity of the concept, in reality this is only one class implemented in two cs files.
Creating the interface might seem to be a lot of work, especially for larger Web Services, but it can easily be generated using the refactor tool [Extract Interface] on the proxy class defined in Reference.cs. The implementation of the partial MyService class stays empty, it only defines the interface IMyService (the implementation of IMyService is in the generated proxy).
For dependency injection I've used a simple factory class that either instantiates the Web Service or, in case of the unit tests, an instance of a mock object defined in the web.config.
However, as easy this is in C# 2.0 it cannot be implemented the same way in VB.NET. The reason is that VB.NET doesn't support implicit interface implementation, you have to define the interface implementation explicitly using the Implements keyword:
Public Function DoSomething() Implements IMyService.DoSomething
This is too bad because you either have to alter Reference.cs (which you shouldn't because when you update the web reference you loose the changes) or implement new properties/functions in the otherwise empty class MyService and map them to the Web Service, which is a lot more work.
The source code can be downloaded from here: WebServiceMockTechnique.zip (62,52 KB)