Something I keep having to look up is testing MVC (5) responses. There are several types of responses you can return on a MVC method:
- Plain ol’ object.
- IHttpActionResult.
- HttpResponseMessage.
Plain ol’ object
Returning an object means that it will be converted to the format in the Request (e.g. JSON, XML). However, you have no direct control over the returned HTTP code. Example: public Person Get(int personId). Testing this is straightforward as you immediately have the result you need. Example:
// Act
Person person = controller.Get(10);
// Assert
Assert.That(person.Id, Is.EqualTo(10));
IHttpActionResult
You can use standard functions as a result, like Ok(myObject) or BadRequest(). Testing is straightforward by casting the return value to the expected result class. Example function: public IHttpActionResult Get(int personId). Testing will look like this:
// Act
IHttpActionResult actionResult = controller.Get(142);
// Assert
Assert.That(actionResult, Is.InstanceOf<NotFoundResult>());
HttpResponseMessage
This gives the most control over the response message. For example: you can set headers or ReasonPhrase. Example: public HttpResponseMessage Get(int personId). Testing requires some extra setup such that the Response Object can be created. Example:
// Arrange
PersonController controller = new PersonController();
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
// Act
var response = controller.Get(10);
// Assert
Assert.IsTrue(response.TryGetContentValue<Person>(out person));
Assert.AreEqual(10, person.Id);
Because of the extra control of the Response we can also test the extra Response properties:
// Arrange
PersonController controller = new PersonController();
controller.Request = new HttpRequestMessage();
controller.Configuration = new HttpConfiguration();
// Act
var response = controller.Get(-1);
// Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
Assert.That(response.ReasonPhrase, Is.EqualTo("Invalid id provided"));
Conclusion
So, there you have it. Three ways to test the different types of controller functions that will return an object. More information can be found at https://docs.microsoft.com/en-us/aspnet/web-api/overview/testing-and-debugging/unit-testing-controllers-in-web-api