Doing an integration test on a web api endpoint what should I put my focus on to assert?
My endpoint is also doing a call to a domain service.
Should I mock that service? With the current code that is not possible, because I would need to instantiate the controller to pass the mock service.
Am I interested in the service return value? actually not. I am only interested wether the endpoint was succesfully triggered but then I should isolate the service call I guess.
Any advice is welcome :-)
TEST
[TestClass]
public class SchoolyearControllerTests
{
private TestServer _server;
[TestInitialize]
public void FixtureInit()
{
_server = TestServer.Create<Startup>();
}
[TestCleanup]
public void FixtureDispose()
{
_server.Dispose();
}
[TestMethod]
public void Get()
{
var response = _server.HttpClient.GetAsync(_server.BaseAddress + "/api/schoolyears").Result;
var result = response.Content.ReadAsAsync<IEnumerable<SchoolyearDTO>>().GetAwaiter().GetResult();
Assert.AreEqual(response.StatusCode, HttpStatusCode.OK);
}
}
Action to test
[HttpGet]
public async Task<IHttpActionResult> Get()
{
var schoolyears = await service.GetSchoolyears();
return Ok(schoolyears);
}
The trouble with doing an integration test on a web service is that it doesn't tell you very much about the problem - or even if there actually is one, and if there is, it doesn't tell you where the issue lies. It will either succeed or fail. So in that respect did you get a 200 response code or a 500 response code... but did it fail because:
It could literally be anything - and result might be different on your dev machine than in production - so what does it really tell you about your application?
What makes for robust software is to test that your product is able to handle any of these situations correctly, gracefully and robustly.
I write my controller actions like this:
A try block gets the data, makes a dto and returns the data with a 200 code. There are several error conditions handled here, but none indicate a problem with my web service itself and some (404 error) don't even indicate an issue with the application - I EXPECT a NotFoundException and a 404 if my application can't find a record - if this happens my application WORKS in this scenario.
So if any of these error conditions occur, its not because there's a problem with the web service, and not necessarily a problem with the app. But I can test that my web service is returning the correct response for any of these expected conditions.
The tests for this controller action looks like this:
Note that I'm introducing a mock respository and having my mock repository trigger the expected exceptions for 404 and server error and ensuring that the web service handles it correctly.
What this tells me is that my web service handling expected and exceptional situations as it should and returning the appropriate codes: 200/404/500.
Although some are error states and some are success states, none of these outcomes indicate a problem with my web service - it is behaving exactly as it should, and that's what I want to test.
An 'across the network' integration test on a web service tells you nothing about the robustness or correctness of your application - or even if its returning the correct data or response-code.
Don't try to re-test WebAPI... Microsoft wrote a massive suite of tests for it already - hundreds of test-fixture classes, thousands of test methods:
https://aspnetwebstack.codeplex.com/SourceControl/latest#test/System.Web.Http.Test/Controllers/ApiControllerTest.cs
Assume that WebAPI works as it should and doesn't require you to test it again. Focus on testing your application code and make sure success and error conditions are handled gracefully by your web service.
If you want to check your web service is connected and available on the network - open a browser and test it manually; there's no need to automate this; the result will vary between environments and according to external conditions.
Test each layer of your application the same way, mock out the layer above and test that the current layer handles every possible outcome from the layer above.
Your client application for your service should do the same thing: Mock the web service, and pretend that it gave a 404 - and check that it handles this as it should.