Web Api – Integration Testing

Sorry, it has been a few months since my last post, time flies by and before you know it, the seasons have changed and you haven’t written a blog post in roughly three months.

Anyway, something that I have been working a lot on lately is creating web api applications for a project that I am involved in for work.  The main purpose of this post will be to try and describe the testing method involved.  This is to try to help with two points. One, when I started I didn’t know a lot about web api and the ways that you could test your newly created api.  This could maybe help someone.  Second, to allow me to have somewhere to dump my brain so when I’m asked again I don’t need to search for the information or spend time on the old problems.

To start with, three blogs that I used were:
In memory client, host and integration testing of your Web API service
ASP.NET Web API integration testing with in-memory hosting
Integration testing ASP .NET Web API

Glenn Block has written a book covering web api
Designing Evolvable Web APIs with ASP.NET

I was also very lucky that someone inside the company I work for had arranged for Glenn Block to talk to the developers and the same person had almost completed the template that we would use to write the api but they had followed a different approach for testing, particularly integration testing.  Going for a self hosted solution and this involved using the full IIS to deploy the application and run tests against that application.  In the project I am involved in, we used IIS Express and changing the web server wasn’t an option plus I had to write tests that could run and safely clean up after themselves in the continuous integration (CI) server. I opted for the in-memory integration tests.

I started off creating an infrastructure library for my configuration classes, interfaces and server class.  The configuration class consisted of all the plumbing for Castle Windsor and routes and filters for my api project and the server classes utilised the configuration classes to set the http configuration and http server to use in my tests. Then called the classes in the infrastructure library from the main api project.  I also had both unit and integration test projects.  I have seen some create an project to house all the models and any other logic necessary.  Essentially use the main api project as a host only but I did not want to create a large number of projects so opted to use my main project to hold the models and some configuration code.

Structure:
– Api – controller and view models.
– Infrastructure – in-memory server and configuration.
– Integration tests – for the api code only.
– Unit tests – for the api code only.

The command and queries that were executed from the api project were all housed in another project and had their own test projects.

One of the main issues that I had was how to dispose of the Castle Windsor container after each test run.  The test harness would only run one test successfully.  It would fail the other tests but if you ran the other tests individually they would pass.  It was not disposing of the classes the way it should or we were not setting the lifecycle up on the classes right.  If we set up the configuration in the constructor of the server class it would fail as well with the same error that it could not dispose of the object.  In the end, a new container was created on each test and this solved the issue.  There was no way to remove the items from an existing container.  I would be interested in hearing from anyone that has solved that problem in a different or better way.

One of the other issues was the serialized auto properties were generating the k_backingfield text and as a result automapper could not resolve the property names.  The data returned was always null.  A couple of ways to resolve this were using [Data Contract] at the top of the class with [Data Member] for each of the properties or using the Newtonsoft.Json Library using the data annotation [JsonProperty] with the k_backingfield added to the name above the property.

One of the things that I did in case we ever wanted to go down the self hosted route was to create an in-memory test class, which inherited the actual test class.  This way it was simple enough to create a self hosted test class, which inherited the actual test class without repeating code or configuration over and over.

Example:
[TestFixture]
public class InMemoryApiTests : ApiTests
{
public InMemorysApiTests() : base(new InMemoryApiServer())
{
}
}

One tool that proved invaluable was the Postman REST client, it is a chrome plugin and I used this to compare the outputs that I got from the tests and the returned data in post value to make sure everything was good.

I have now implemented another api and this time it was a lot easier because I could use the pattern developed earlier to test.  Testing was by the far the greatest challenge that I faced when developing the api.

Until next time…..As ever any feedback on the way I write these posts or the content is appreciated.