Unit testing controller methods which return IActionResult

You can also do cool things like:

    var result = await controller.GetOrders();//
    var okResult = result as ObjectResult;

    // assert
    Assert.NotNull(okResult);
    Assert.True(okResult is OkObjectResult);
    Assert.IsType<TheTypeYouAreExpecting>(okResult.Value);
    Assert.Equal(StatusCodes.Status200OK, okResult.StatusCode);

Thanks


Other answers adviced to cast to ObjectResult, but its work only if you return OkObjectResult \ NotFoundObjectResult \ etc. But server could return NotFound\ OkResult which derived from StatusCodeResult.

For example:

public class SampleController : ControllerBase
{
    public async Task<IActionResult> FooAsync(int? id)
    {
        if (id == 0)
        {
            // returned "NotFoundResult" base type "StatusCodeResult"
            return NotFound();
        }

        if (id == 1)
        {
            // returned "StatusCodeResult" base type "StatusCodeResult"
            return StatusCode(StatusCodes.Status415UnsupportedMediaType);
        }

        // returned "OkObjectResult" base type "ObjectResult"
        return new OkObjectResult("some message");
    }
}

I looked at the implementation of all these methods and found that they are all inherited from the IStatusCodeActionResult interface. It seems like this is the most base type that contains StatusCode:

private SampleController _sampleController = new SampleController();

[Theory]
[InlineData(0, StatusCodes.Status404NotFound)]
[InlineData(1, StatusCodes.Status415UnsupportedMediaType)]
[InlineData(2, StatusCodes.Status200OK)]
public async Task Foo_ResponseTest(int id, int expectedCode)
{
    var actionResult = await _sampleController.FooAsync(id);
    var statusCodeResult = (IStatusCodeActionResult)actionResult;
    Assert.Equal(expectedCode, statusCodeResult.StatusCode);
}

Assuming something like the

public IActionResult GetOrders() {
    var orders = repository.All();
    return Ok(orders);
}

the controller in this case is returning an OkObjectResult class.

Cast the result to the type of what you are returning in the method and perform your assert on that

[Fact]
public void GetOrders_WithOrdersInRepo_ReturnsOk() {
    // arrange
    var controller = new OrdersController(new MockRepository());

    // act
    var result = controller.GetOrders();
    var okResult = result as OkObjectResult;

    // assert
    Assert.IsNotNull(okResult);
    Assert.AreEqual(200, okResult.StatusCode);
}