Unit Testing .NET Core 2 Web Api

Full source code available here.

Unit testing Web API controllers in .NET Core 2 is very easy.

I have very simple GET and POST methods.

[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet]
    public async Task<IActionResult> Get()
    {
        // imagine some db logic
        List<string> values = new List<string>() { "value1", "value2" };
        return Ok(values);
    }

    [HttpPost]
    public async Task<IActionResult> Post([FromBody]string value)
    {
        // imagine some db logic
        return Created("", value);
    }
}

Add an xUnit Test Project to your solution.

In the test project add a ValuesControllerTests class.

Add a method to test the ValuesController.Get like this –

[Fact]
public async Task TestGet()
{
    // Arrange
    var controller = new ValuesController();

    // Act
    IActionResult actionResult = await controller.Get();

    // Assert
    Assert.NotNull(actionResult);

    OkObjectResult result = actionResult as OkObjectResult;

    Assert.NotNull(result);

    List<string> messages = result.Value as List<string>;

    Assert.Equal(2, messages.Count);
    Assert.Equal("value1", messages[0]);
    Assert.Equal("value2", messages[1]);
}

Note here how I expect the result to be an OkObjectResult

OkObjectResult result = actionResult as OkObjectResult;

And here where I cast the result.Value as List, the type I sent from the controller. No deserializing from json, strings or byte arrays needed!

List<string> messages = result.Value as List<string>;

Now it is simple to perform the appropriate asserts.

Here is another example, this time testing the ValuesController.Post().

[Fact]
public async Task TestPost()
{
    // Arrange
    var controller = new ValuesController();

    // Act
    IActionResult actionResult = await controller.Post("Some value");

    // Assert
    Assert.NotNull(actionResult);
    CreatedResult result = actionResult as CreatedResult;

    Assert.NotNull(result);
    Assert.Equal(201, result.StatusCode);
} 

You can also test a result for NotFoundResult, OkResult, UnauthorizedResult, etc.

Full source code available here.