Reputation: 21
In C#, how in the world do I get the HTTP status number (200) and return text ("ok") in this case for unit testing for an API controller? I think I've tried everything. Surely this is a common need. Thanks.
public IHttpActionResult Get(string appServer, string action)
{
return Ok("ok");
}
[TestMethod]
public void AppPoolTestStart()
{
AppPoolController controller = new AppPoolController();
IHttpActionResult result = controller.Get("MyServer", "start");
Assert.??? ; // check for 200 or "ok"
}
Upvotes: 2
Views: 7611
Reputation: 596377
Per Action Results in Web API 2:
A Web API controller action can return any of the following:
- void
- HttpResponseMessage
- IHttpActionResult
- Some other type
Depending on which of these is returned, Web API uses a different mechanism to create the HTTP response.
void
Return empty 204 (No Content)HttpResponseMessage
Convert directly to an HTTP response message.IHttpActionResult
Call ExecuteAsync to create an HttpResponseMessage, then convert to an HTTP response message.Other type Write the serialized return value into the response body; return 200 (OK).
...
IHttpActionResult
The IHttpActionResult interface was introduced in Web API 2. Essentially, it defines an HttpResponseMessage factory. Here are some advantages of using the IHttpActionResult interface:
- Simplifies unit testing your controllers.
- Moves common logic for creating HTTP responses into separate classes.
- Makes the intent of the controller action clearer, by hiding the low-level details of constructing the response.
IHttpActionResult contains a single method, ExecuteAsync, which asynchronously creates an HttpResponseMessage instance.
public interface IHttpActionResult { Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken); }
If a controller action returns an IHttpActionResult, Web API calls the ExecuteAsync method to create an HttpResponseMessage. Then it converts the HttpResponseMessage into an HTTP response message.
So, in your case, you can call result.ExecuteAsync()
and wait for the resulting Task
to complete, then obtain its HttpResponseMessage
object.
However, there is a different way to approach this, and it is covered in more detail in the following documentation:
Unit Testing Controllers in ASP.NET Web API 2
In particular, see the section on "Testing Actions that Return IHttpActionResult":
In Web API 2, a controller action can return IHttpActionResult, which is analogous to ActionResult in ASP.NET MVC. The IHttpActionResult interface defines a command pattern for creating HTTP responses. Instead of creating the response directly, the controller returns an IHttpActionResult. Later, the pipeline invokes the IHttpActionResult to create the response. This approach makes it easier to write unit tests, because you can skip a lot of the setup that is needed for HttpResponseMessage.
In the examples given, they simply type-cast the IHttpActionResult
to the desired Response type they are testing for. For example:
// Act
IHttpActionResult actionResult = controller.Get(42);
var contentResult = actionResult as OkNegotiatedContentResult<Product>;
// Assert
Assert.IsNotNull(contentResult);
Assert.IsNotNull(contentResult.Content);
Assert.AreEqual(42, contentResult.Content.Id);
// Act
IHttpActionResult actionResult = controller.Get(10);
// Assert
Assert.IsInstanceOfType(actionResult, typeof(NotFoundResult));
// Act
IHttpActionResult actionResult = controller.Delete(10);
// Assert
Assert.IsInstanceOfType(actionResult, typeof(OkResult));
And so on.
Upvotes: 4