web-dev-qa-db-fra.com

Contexte Mocking Entity Framework Core

J'essaie de tester mon application afin de me moquer de mon contexte EF.

Mon code semble être ok, mais j'ai l'exception suivante:

"System.ArgumentNullException: la valeur ne peut pas être nulle. Nom du paramètre: Source"

Voici ma méthode de test: 

  var options = new DbContextOptionsBuilder<ProductContext>().Options;
    var settings = new SqlSettings
    {
        InMemory = true
    };

    var context = new Mock<ProductContext>(options, settings);
    var mockTreeService = new TreeService(context.Object);
    await mockTreeService.CreateTreeAsync("Testing tree", Guid.NewGuid());

    context.Verify(x => x.AddAsync(It.IsAny<Tree>(), CancellationToken.None), Times.Once);

On dirait que cette expérience est lancée lors de l'exécution de cette pièce de code 

            var tree = await _context.Trees
                .Include(x => x.Translation)
                .FirstOrDefaultAsync(x => x.Translation.Pl == name);

Cela vient de mon service que je teste

5
bielu000

Je pense que cela est dû au fait de ne pas avoir de chaîne de connexion. Franchement, il est un peu difficile de reproduire entièrement la variable DbContext, raison pour laquelle l’équipe EF Core a fourni une implémentation en mémoire. C'est beaucoup plus facile de travailler à des fins de test. Modifiez simplement votre initialisation options en:

var options = new DbContextOptionsBuilder<ProductContext>()
                  .UseInMemoryDatabase(Guid.NewGuid().ToString())
                  .Options;

Ensuite, vous devrez renseigner la base de données avec vos données de test. Ensuite, vous pouvez exécuter le reste de votre test.

Remarque: si vous utilisez la base de données en mémoire, vous n'avez plus besoin de vous moquer du contexte pour pouvoir supprimer ce morceau de code. La base de données en mémoire est essentiellement une simulation.

10
Chris Pratt

J'ai utilisé cette https://github.com/huysentruitw/entity-framework-core-mock library. Très facile et peut écrire un test unitaire en utilisant moins de codage.

Vous pouvez utiliser la plupart des méthodes Moq si vous utilisez le framework moq.

Vous trouverez ci-dessous un exemple de code pour tester DBQuerys.

public async Task<Boat> GetByIdAsync(string id)
    => await _boatContext.Boats.Where(x => x.id == id).FirstOrDefaultAsync();

[Fact]
public async Task GetByIdAsync_WhenCalled_ReturnsItem()
{
    // Arrange
    var models = new[] { new Boat { id = "p1" } };
    var dbContextMock = new DbContextMock<BoatContext>();
    dbContextMock.CreateDbQueryMock(x => x.Boats, models);

    var service = new Properties(dbContextMock.Object);

    // Act
    var okResult = await service.GetByIdAsync("p1");

    // Assert
    Assert.IsType<Boat>(okResult.Result);
}

Publier ici cela peut aider quelqu'un :) 

1
cdev