Why and how would I Mock a Web Service? (In VS 2005)?
Well, in my current project, this question appeared very early on. Since, I am doing Test-Driven Development, I need to test my web service data layer, but I don’t need it all of the time. I used a pattern called Constructor based Dependency Injection. This allows you to replace the service with a different implementation. For my situation, the implementation is for removing an external dependency for testing. I removed this dependency, by mocking the object with NMock. NMock allows you to pass parameters, setup return values, exceptions and do sequence actions.
Download location: https://nmock.org/download.html
Now for the implementation, so here come the 2.0 Framework to the rescue. When you add a web service, a reference.cs or (reference.vb) file gets created in the directory with the web service WSDL. Fortunately, this class is created as a partial class; I used this knowledge to create another partial class that I can control. You don’t really want to update the reference.cs or .vb class from the web service, because it can change when you update the web service reference and all of your changes are gone. The summary below details the steps that are required to implement this.
Summary:
(Step 1, setup Constructor based Dependency Injection)
- Create a partial class with the proper namespace and class name for your web service.
- Define an interface for the methods that will be consumed from the web service.
- Update the partial class in step 1, to use interface.
- Implement Interface methods with this.<methodname> from web service.
- Define a private member variable that will consume the Interface.
- Create a constructor for your Web Service Data Access object that will use the interface.
(Step 2: Setup NMock and Mock service calls)
- Create a mock object. (Ex: Mockery mock = new Mockery() )
- Create mock of Interface object: ( Ex: IMyService service = mock.NewMock<IMyService>(); )
- Define what will be returned, or expected behavior. Expect.Once.On(service).Method(“MyCall”).Will(Return.Value(expected));
- Verify that everthing worked correctly.mock.VerifyAllExpectationsHaveBeenMet();
// Provider that will consume the web service.
public class Provider
{
private IService apservice;
public Provider()
{
this.apservice = new MyWebService();
}
/// <summary>
/// Constructor that allows NMock testing
/// </summary>
/// <param name="service">Interface for Web Service</param>
public Provider(IMyService service)
{
this.apservice = service;
}
public string Method1(string name)
{
return apservice.MyCall(name,string.Empty);
}
}
// Interface for the Web Service
public interface IDiscussionService
{
Results MyCall(string param1,string param2);
}
// Partial class for the Web Service
public partial class MyWebService : System.Web.Services.Protocols.SoapHttpClientProtocol, IMyService
{
string IMyService.MyCall(string param1, string param2)
{
return this.MyCall(param1, param2);
}
}
//Unit Test that will NMock the web service[TestMethod] public void GetSitesTest() {
Mockery mock = new Mockery();IMyService service = mock.NewMock<IMyService>();
String expected = “Hello World”;Expect.Once.On(service).Method("MyCall").Will(Return.Value(expected));Provider target = new SiteProvider(service);
string actual = target.Method1(“Name”);
Assert.AreEqual(expected,actual);mock.VerifyAllExpectationsHaveBeenMet();
}
References:
Tags: NMock, Web Services, Injection, TDD
Comments
- Anonymous
September 01, 2006
My colleague, Greg, and I spent all day debugging a build break in some unit tests that exercise a webservice