views:

878

answers:

2

I created some POX services using the REST Starter kit. At first, it was a little complicated to create the unit tests for the service layer, but in the end, it was well designed and I succeed in mocking the context and set expectations.

But, I'm starting in with the client side now, and I'm having some problems figuring out how to mock things. It's not so straight forward.

So, I have this sample method that post via HTTP some data using a datacontract and XML as transport.

public class ServiceClient: IService

{
    private const string uri_template = "http://{0}:{1}/SomeService.svc/";
    private readonly HttpClient http = new HttpClient();

    public ServiceClient(string host, int port)
    {
        http.BaseAddress = new Uri(string.Format(uri_template , host, port));
    }

    public void Create(MyDataContract my_data_contract)
    {
        var content = HttpContentExtensions
                        .CreateDataContract(
                          my_data_contract, 
                          Encoding.Default, 
                          "text/xml", 
                          null);
        var response = http.Post("Create", content);
        if (response.StatusCode != HttpStatusCode.Created) {
            throw new Exception("something is not right");
        }
    }
}

This method is working and indeed posting the data and serializing correctly.

What I want to do, is to unit test it.

My questions are:

  1. How do I make stubs/mocks for HttpContextExtensions knowing that it does not implement any interface?

  2. And for HttpClient? this is worst since it is full of extension methods defined elsewhere (Post and the like methods are extensions).

In 2. I guess I can stick to 'Send' and it's overloads, but then is the same problem as in 1

What I was thinking to do, is to extract interfaces for HttpContextExtensions and HttpClient, make a children for each one and implement the interfaces delegating to the parent, and then using the interfaces in my code.

But that's a lot of work IMHO.

I'm using RhinoMocks as my mocking framework so I can't mock/stub concrete classes, and I would like to stick to it, because I really think that mocking concrete classes is not very elegant.

So, is there a cleaner/faster/smarter way to unit test code like the above?

PD: This is for WCF Starter Kit preview 2

+1  A: 

Hi David,

If you really want to mock that code, an approach that could work for this scenario is to receive an HttpClient instance in the ServiceClient class. The HttpClient class contains a processing pipeline that you can customize with custom handlers. For your tests, you can basically inject a handler in that httpclient instance to return a mocked response to the test before the real service is called in the last handler (Transport Stage). Take a look at this post to get an idea about how this can be implemented,

http://weblogs.asp.net/cibrax/archive/2009/03/18/negotiating-a-saml-token-for-rest-clients-with-httpclient.aspx

Regards, Pablo.

Thanks Pablo. I took your advice, but gave it a simplier implmentation, but just because was all I needed.I followed yours writings here http://weblogs.asp.net/cibrax/archive/2009/03/13/httpclient-in-the-wcf-rest-starter-kit-preview-2.aspx and made my own HttpStage child class just for testing purposes, and configurable to return any response. Thanks.
David Lay
+1  A: 

I wrote most of the HttpClient code. Pablo's suggestion is what I did in the unit tests -- see FixedTransport.cs in the source zip.

JLamb
I don't know why I didn't thought to look in the source of the kit. obvious!! >_< ...
David Lay