I'm fairly new to unit testing but I'm trying to incorporate it into my development process for any new code I write (including bug fixes).
I'm working a REST client to communicate with Highrise (37Signals). How can I unit test this without relying on the external dependency? (The REST service).
For instance I'll have a method called GetPeople()
Things I'll want to unit test...
What do I do to test that the service still functions the same. I.E person still has a First Name? Can I unit test this or is this more of an integration test?
I assume that your code now uses HttpWebRequest
and HttpWebResponse
directly. If that's the case, replace all occurrences of HttpWebRequest
with IRequest
and HttpWebResponse
with IResponse
. Defined these two interfaces and expose the properties and methods you need, like so:
public interface IRequest
{
IResponse GetResponse(string url);
IResponse GetResponse(string url, object data);
}
public interface IResponse
{
Stream GetStream();
}
Then it's just to implement these interfaces twice; once for the real application (using HttpWebRequest
and HttpWebResponse
for doing the HTTP stuff) and once for the tests (not using HTTP, but instead perhaps writing to the console, a log or something similar).
Then, when instantiating your client, it's just to inject the implementation of IRequest
you want:
var realClient = new Client(new MyHttpRequest());
var testClient = new Client(new MyTestRequest());
For all those who are trying to test actual HttpWebRequest and HttpWebResponse, rather than the mocks. I have mentioned an approach here: http://nripendra-newa.blogspot.com/2012/10/testing-rest-clients.html. I'd call it an integration test rather than unit test though. Please refer here to see practical implementation: https://github.com/nripendra/Resty.Net/blob/master/tests/Resty.Net.Tests/RestRequestTest.cs
The approach:
It is a very common requirement to unit test code that interacts with external REST APIs. Simulating API servers is actually really annoying to set up usually because most web frameworks require lots of configuration before you can even begin to mock out endpoints. For example NancyFX and Asp.net.
In addition to this it can be really hard to assert the data that was sent to the server - essentially meaning you can only check that the response is handled correctly.
Even doing integration testing on the real endpoint you can't test what happens when the API you are using goes down or outputs an unusual status code, because you have no control over the endpoint.
After a long time trying to find a solution to this problem I decided to write a library for mocking out API endpoints using a real web server based on the built in HttpListener class.
https://github.com/paulmorrishill/FluentSimulator
This library supports simulating endpoints, headers, responses, slow responses, failed responses. Every type of event that can occur on an HTTP endpoint.
It also allows asserting that the data sent to the server was exactly what you expected it to be.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With