2016-11-08 1 views
-1

J'essaie de créer un test pour tester la structure de l'entité Add. Quelqu'un peut-il aider à se moquer de la méthode DbSet.Add. J'ai essayé comme ci-dessous, mais ne fonctionne pas. Qu'est-ce que je fais mal?C# Comment Moq entityframework DbSet Ajouter une méthode

Le résultat que je reçois est null après repository.Insert ...

Test.cs:

var productToCreate = new Product { Name = "Added", Description = "Added" };   

var result = repository.InsertAsync(objToCreate, userContext).Result; 
Assert.AreEqual(result.Name, "Added"); 

Mock.cs

internal static DbSet<T> GetMockedDataSet<T>(IEnumerable<T> data) where T : class 
{ 
    // Create a mocked data set that contains the data 
    var set = new Mock<DbSet<T>>(); 
    set.As<IDbAsyncEnumerable<T>>() 
     .Setup(m => m.GetAsyncEnumerator()) 
     .Returns(new TestDbAsyncEnumerator<T>(data.GetEnumerator())); 
    set.As<IQueryable<T>>() 
     .Setup(m => m.Provider) 
     .Returns(new TestDbAsyncQueryProvider<T>(data.AsQueryable().Provider)); 
    set.As<IQueryable<T>>().Setup(m => m.Expression).Returns(data.AsQueryable().Expression); 
    set.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(data.AsQueryable().ElementType); 
    set.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(data.GetEnumerator()); 

    set.Setup(x => x.AsNoTracking()).Returns(set.Object); 
    set.Setup(x => x.Add(It.IsAny<T>())).Callback<T>((s) => data.Concat(new[] { s })); 

    // Return the mock 
    return set.Object; 
} 

Repository:

public async Task<Product> InsertAsync(Product input) 
{ 
    using (var ctx = .....)) 
    { 
     var added = ctx.Set<Product>().Add(input); 

     await ctx.ValidateAndSaveAsync(); 

     return added; 
    } 
} 
+1

Fournissez un [mcve] qui reproduit le problème. – Nkosi

+0

@Nkosi, désolé, je ne comprends pas ce que tu veux dire? J'ai fourni mon code et expliqué ce que j'attendais. Merci –

+1

Cet exemple est incomplet. trop de variables dépendantes sont inconnues pour être en mesure de recréer le problème, la méthode sous test est différente de ce qui a été montré dans le test, la configuration indiquée est incomplète .... ai-je besoin de continuer? – Nkosi

Répondre

2

Selon la façon dont la méthode Add est utilisée dans la méthode à l'essai ...

var added = ctx.Set<Product>().Add(input); 

... il devrait aussi y avoir un Returns dans la configuration qui renvoie l'argument qui a été saisi, si cela est souhaité fonctionnalité.

set.Setup(x => x.Add(It.IsAny<T>())) 
    .Returns<T>(arg => arg) 
    .Callback<T>((s) => data.Concat(new[] { s })); 

Mais étant donné que les informations sur la dépendance de contexte est inconnu ...

using (var ctx = .....)) 

il est incertain que la solution proposée aura l'effet désiré.

De plus, si vous testez une méthode asynchrone, ne mélangez pas les appels asynchrones et synchrones. La ligne suivante ...

var result = repository.InsertAsync(objToCreate, userContext).Result; 

... peut provoquer des blocages.

Rendre la méthode de test async complètement.

[TestMethod] 
public async Task InsertAsync_Should_Return_Product() { 
    //...other code 

    var expected = new Product { Name = "Added", Description = "Added" };   

    var actual = await repository.InsertAsync(expected, userContext); 

    Assert.AreEqual(expected.Name, actual.Name); 
} 
+0

Wow! Cela a fonctionné comme le charme. Je vous remercie. J'ai changé le testmethod pour utiliser async. merci encore –

+0

Note latérale - Votre rappel sur la méthode add ne fait rien. cela n'a aucun effet sur la collection originale fournie. – Nkosi