I'm in the process of building an ASP.NET Core WebAPI and I'm attempting to write unit tests for the controllers. Most examples I've found are from the older WebAPI/WebAPI2 platforms and don't seem to correlate with the new Core controllers.
My controller methods are returning IActionResults.  However, the IActionResult object only has a ExecuteResultAsync() method which requires a controller context.  I'm instantiating the controller manually, so the controller context in this instance is null, which causes an exception when calling ExecuteResultAsync.  Essentially this is leading me down a very hacky path to get these unit tests to successfully complete and is very messy. I'm left wondering that there must be a more simple/correct way of testing API controllers.
Also, my controllers are NOT using async/await if that makes a difference.
Simple example of what I'm trying to achieve:
Controller method:
[HttpGet(Name = "GetOrdersRoute")] public IActionResult GetOrders([FromQuery]int page = 0) {      try      {         var query = _repository.GetAll().ToList();          int totalCount = query.Count;         int totalPages = (int)Math.Ceiling((double)totalCount / pageSize) - 1;         var orders = query.Skip(pageSize * page).Take(pageSize);          return Ok(new         {            TotalCount = totalCount,            TotalPages = totalPages,             Orders = orders         });      }      catch (Exception ex)      {         return BadRequest(ex);      } }   Unit test:
[Fact] public void GetOrders_WithOrdersInRepo_ReturnsOk() {      // arrange      var controller = new OrdersController(new MockRepository());       // act      IActionResult result = controller.GetOrders();       // assert      Assert.Equal(HttpStatusCode.OK, ????); } 
                The IActionResult return type is appropriate when multiple ActionResult return types are possible in an action. The ActionResult types represent various HTTP status codes. Any non-abstract class deriving from ActionResult qualifies as a valid return type.
Yeah I think it does. The unit tests will test individual functionality and also provide you with a means to test if the unit was broken when other code changed. The integration test then tests the end-to-end process.
First we need to add an employee class in the Models folder. Following is the Employee class implementation. We need to add EmployeeController. Right-click on the controller folder in the solution explorer and select Add → Controller.
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); } 
                        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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With