web-dev-qa-db-fra.com

Test d'unité d'un contrôleur d'API Web

Je suis relativement nouveau dans les tests unitaires et j'essaie de créer un test unitaire pour un contrôleur d'API Web que j'ai créé qui renvoie une liste de marques.

Ma méthode de contrôleur Web API Get() ressemble à ceci:

[HttpGet("/api/Brands/Get", Name = "GetBrands")]
public async Task<IActionResult> Get()
{
    var brands = await _brandsService.GetAll(null, "Image");
    return Json(brands);
}

La méthode de service générique ressemble à ceci:

public async Task<List<T>> GetAll(
    Func<IQueryable<T>, 
    IOrderedQueryable<T>> orderBy = null, 
    string includeProperties = null)
{
    return await _genericRepository.GetAll(orderBy, includeProperties);
}

et la méthode de dépôt générique ressemble à ceci:

public async Task<T> Get<TKey>(Expression<Func<T, bool>> filter = null, string includeProperties = "", bool noTracking = false)

{
    includeProperties = includeProperties.Trim() ?? string.Empty;
    IQueryable<T> query = Context.Set<T>();

    if (noTracking)
    {
        query.AsNoTracking();
    }

    if (filter != null)
    {
        query = query.Where(filter);
    }

    foreach (var includeProperty in includeProperties.Split
        (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
    {
        query = query.Include(includeProperty);
    }

    return await query.SingleOrDefaultAsync();
}

Cela fonctionne et je renvoie une liste de marques de la base de données.

Maintenant, j'ai essayé de créer un test unitaire pour cela:

[SetUp]
public void Setup()
{
    Brands = new List<Brand>
    {
        new Brand
        {
            Id = 1,
            Name = "Adidas",
            ImageId = 1
        },
        new Brand
        {
            Id = 2,
            Name = "Nike",
            ImageId = 2
        },
        new Brand
        {
            Id = 3,
            Name = "Puma",
            ImageId = 3
        }
    };
}

[Test]
public async Task Get_ReturnsAAListOfBrands()
{
    //Arrange
    var mockService = new Mock<IGenericService<Brand>>();
    mockService.Setup(repo => repo.GetAll(null, null)).Returns(Task.FromResult(Brands));
    var controller = new BrandsController(mockService.Object);

    //Act
    var result = await controller.Get();
    //Assert
}

cependant, le résultat est toujours nul. Suis-je en train de tester correctement ou dois-je changer mon code de test unitaire pour vérifier que le service factice a trois éléments stockés?

10
Johann

Vous devez configurer la configuration pour attendre un comportement ou un argument particulier pour le test.

Dans ce cas, l'utilisation de la fonction It.IsAny<T>() pour indiquer à la configuration à quoi s'attendre en termes d'arguments permettra au test de se dérouler comme vous le souhaitez.

Étant donné que la méthode GetAll nécessite deux paramètres de Func<IQueryable<T>, IOrderedQueryable<T>> et string, le programme d'installation configure ce qu'il faut faire en fonction des valeurs entrées pour ces paramètres.

[Test]
public async Task Get_ReturnsAAListOfBrands() {
    //Arrange
    var mockService = new Mock<IGenericService<Brand>>();
    mockService
        .Setup(repo => repo.GetAll(It.IsAny<Func<IQueryable<Brand>, IOrderedQueryable<Brand>>>(), It.IsAny<string>()))
        .ReturnsAsync(Brands);
    var controller = new BrandsController(mockService.Object);

    //Act
    var result = await controller.Get();
    //Assert
    //...
}

Jetez un oeil à la Moq Quickstart pour une meilleure compréhension de la façon d'utiliser ce cadre de simulation

5
Nkosi