webentwicklung-frage-antwort-db.com.de

Unit-Testing-Controller-Methoden, die IActionResult zurückgeben

Ich bin gerade dabei, eine ASP.NET Core-WebAPI zu erstellen, und ich versuche, Komponententests für die Controller zu schreiben. Die meisten Beispiele, die ich gefunden habe, stammen von älteren WebAPI/WebAPI2-Plattformen und scheinen nicht mit den neuen Core-Controllern zu korrelieren.

Meine Controller-Methoden geben IActionResults zurück. Das IActionResult -Objekt verfügt jedoch nur über eine ExecuteResultAsync() -Methode, für die ein Controller-Kontext erforderlich ist. Ich instanziiere den Controller manuell, daher ist der Controller-Kontext in dieser Instanz null, was zu einer Ausnahme führt, wenn ExecuteResultAsync aufgerufen wird. Im Grunde genommen führt mich dies auf einen sehr schlechten Weg, um diese Komponententests erfolgreich abzuschließen, und es ist sehr chaotisch. Ich frage mich, ob es eine einfachere/korrektere Methode zum Testen von API-Controllern geben muss.

Außerdem verwenden meine Controller NICHT async/await, wenn dies einen Unterschied macht.

Ein einfaches Beispiel für das, was ich erreichen möchte:

Controller-Methode:

[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);
     }
}

Gerätetest:

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

     // act
     IActionResult result = controller.GetOrders();

     // assert
     Assert.Equal(HttpStatusCode.OK, ????);
}
41

Angenommen, so etwas wie das

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

in diesem Fall gibt der Controller eine OkObjectResult -Klasse zurück.

Konvertieren Sie das Ergebnis in den Typ dessen, was Sie in der Methode zurückgeben, und führen Sie Ihre Behauptung dazu durch

[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);
}
59
Nkosi

Sie können auch coole Dinge tun wie:

    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);

Vielen Dank

4
Ernest