web-dev-qa-db-fra.com

Méthodes de contrôleur de test unitaire qui renvoient IActionResult

Je suis en train de créer une WebAPI ASP.NET Core et j'essaie d'écrire des tests unitaires pour les contrôleurs. La plupart des exemples que j'ai trouvés proviennent d'anciennes plates-formes WebAPI/WebAPI2 et ne semblent pas être en corrélation avec les nouveaux contrôleurs Core.

Mes méthodes de contrôleur renvoient IActionResults. Cependant, l'objet IActionResult ne possède qu'une méthode ExecuteResultAsync() qui nécessite un contexte de contrôleur. J'instancie le contrôleur manuellement. Le contexte du contrôleur dans cette instance est donc null, ce qui provoque une exception lors de l'appel de ExecuteResultAsync. En gros, cela m’entraîne sur une voie très difficile pour que ces tests unitaires se terminent avec succès et est très compliqué. Je me demande s'il doit exister une méthode plus simple/correcte pour tester les contrôleurs API.

De plus, mes contrôleurs n'utilisent PAS async/wait si cela fait une différence.

Exemple simple de ce que j'essaie de réaliser:

Méthode du contrôleur:

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

Test de l'unité:

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

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

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

En supposant que quelque chose comme le

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

le contrôleur dans ce cas renvoie une classe OkObjectResult .

Attribuez le résultat au type de ce que vous retournez dans la méthode et effectuez votre affirmation à ce sujet.

[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

Vous pouvez également faire des choses cool comme:

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

Merci

4
Ernest