views:

65

answers:

3

I have some integration tests where I want to verify certain requires are made against a third-[arty webserver. I was thinking I would replace the third-party server with a stub server that simply logs calls made to it. The calls do not need to succeed, but I do need a record of the requests made (mainly just the path+querystring).

I was considering just using IIS for this. I could 1) set up an empty site, 2) modify the system's host file to redirect requests to that site 3) parse the log file at the end of each test.

This is problematic as for IIS the log files are not written to immediately, and the files are written to continuosly. I'll need to locate the file, read the contents before the test, wait a nondeterministic amount of time after the test, read the update contents, etc.

Can someone think of a simpler way?

+2  A: 

You could use the System.Net.HttpListener ( http://msdn.microsoft.com/de-de/library/system.net.httplistener(VS.80).aspx ).

It works as embedded WebServer, this means you can even check the access on-the-fly without having to parse log files.

A class i used in my Code recently:

class Listener
{
    private HttpListener listener = null;

    public event EventHandler CommandReceived;

    public Listener()
    {
        this.listener = new HttpListener();
        this.listener.Prefixes.Add("http://localhost:12345/");
    }

    public void ContextReceived(IAsyncResult result)
    {
        if (!this.listener.IsListening)
        {
            return;
        }
        HttpListenerContext context = this.listener.EndGetContext(result);
        this.listener.BeginGetContext(this.ContextReceived, this.listener);

        if (context != null)
        {
            EventHandler handler = this.CommandReceived;
            handler(context, new EventArgs());
        }
    }

    public void Start()
    {
        this.listener.Start();
        this.listener.BeginGetContext(this.ContextReceived, this.listener);
    }

    public void Stop()
    {
        this.listener.Stop();
    }
dbemerlin
Cool solution, but I don't exactly think it's neccessary in this case. Useful to know though (hence upvote).
Noon Silk
A: 

Yeah, I don't think you need a whole webserver. You don't need to test HTTP.

What you do need to test is the underlying data structure that you're sending and receiving. So just create tests for that (i.e. make a point at which you can validate your generate dataformat with what is expected, and also with what you intend to receive, etc).

Test the data, not the protocol (unless, obviously, the protocol is custom).

Noon Silk
+1  A: 

I've done something very similar to this in a number of projects.

You don't want to create stubbed web service. That's just adding a dependency you don't need. What I did was create an interface which mimics the web service's API. I then created a proxy class that will call the web service in the live system. For testing I used RhinoMocks to create mocked classes that return the results I wanted to test for. This was very useful for me, as I could then produce all sorts of 'unexpected' behaviour which wouldn't be possible with the live system.

public interface IServiceFacade {
    string Assignments();
}

public class ServiceFacade : IServiceFacade {
    private readonly Service _service;

    public ServiceFacade(Service service) {
        _service = service;
    }

    public string Assignments() {
        return _service.Assignments();
    }
}

Then my test code contained stuff like this:

        var serviceFacade = MockRepository.GenerateMock<IServiceFacade>();
        serviceFacade.Stub(sf => sf.Assignments()).Return("BLAH BLAH BLAH");

or

        serviceFacade.Stub(sf => sf.Assignments()).Return(null);

or

        serviceFacade.Stub(sf => sf.Assignments()).Throw(new Exception("Some exception"));

I found this very useful.

Chris Kemp
Thanks but I really do want to do an integration test in this case. The last mile in functionality is a third party library with undocumented behavior, so I don't want to mock. I agree mocks are great for unit testing.
Frank Schwieterman