Se moquant EF DbContext Moq
Je suis en train de créer un test unitaire pour mon service avec un moqué DbContext. J'ai créé une interface IDbContext
avec les fonctions suivantes:
public interface IDbContext : IDisposable
{
IDbSet<T> Set<T>() where T : class;
DbEntityEntry<T> Entry<T>(T entity) where T : class;
int SaveChanges();
}
Mon contexte réel implémente cette interface IDbContext
et DbContext
.
Maintenant, je suis en train d'essayer de se moquer de l' IDbSet<T>
dans le contexte, elle retourne un List<User>
à la place.
[TestMethod]
public void TestGetAllUsers()
{
//Arrange
var mock = new Mock<IDbContext>();
mock.Setup(x => x.Set<User>())
.Returns(new List<User>
{
new User { ID = 1 }
});
UserService userService = new UserService(mock.Object);
//Act
var allUsers = userService.GetAllUsers();
//Assert
Assert.AreEqual(1, allUsers.Count());
}
J'ai toujours cette erreur sur .Returns
:
The best overloaded method match for
'Moq.Language.IReturns<AuthAPI.Repositories.IDbContext,System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>.Returns(System.Func<System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>)'
has some invalid arguments
- Bien que ce post vous sera utile , je pense qu'il serait plus si vous avez inclus la mise en œuvre de la Moq DbContext , merci pour l'idée .
Vous devez vous connecter pour publier un commentaire.
J'ai réussi à le résoudre en créant une
FakeDbSet<T>
classe qui implémenteIDbSet<T>
Maintenant mon test ressemble à ceci:
async
EF surcharges, voir iciMerci Gaui pour votre grande idée =)
J'ai ajouté quelques améliorations à votre solution et que vous souhaitez partager.
FakeDbSet
aussi inherents deDbSet
pour obtenir d'autres méthodescomme
AddRange()
ObservableCollection<T>
avecList<T>
pour passer tous lesla déjà mis en œuvre des méthodes de
List<>
jusqu'à monFakeDbSet
Mon FakeDbSet:
Il est très facile de modifier les dbSet et se moquent de l'EF Objet de Contexte:
Maintenant, il est possible d'exécuter des requêtes Linq, mais il faut être conscient que la clé étrangère références peuvent ne pas être créés automatiquement:
Parce que l'objet de contexte est moqué de la
Context.SaveChanges()
de ne pas faire n'importe quoi et des changements de propriété de votre entités peuvent ne pas être renseignés pour votre dbSet. J'ai résolu ce problème en se moquant de monSetModifed()
méthode pour remplir les modifications.Au cas où quelqu'un s'est toujours intéressée, j'ai eu le même problème et trouvé cet article très utile:
Entity Framework de Test avec un Moqueur Cadre (EF6 à partir)
Elle ne s'applique qu'à Entity Framework 6 ou plus récent, mais il couvre tout, de la simple SaveChanges tests async des tests de requête utilisant tous Moq (et quelques-uns de manuel de classes).
Si quelqu'un est toujours à la recherche de réponses que j'ai mis en place un petite bibliothèque pour permettre moqueur DbContext.
étape 1
Installer Coderful.EntityFramework.Les tests nuget package:
Install-Package Coderful.EntityFramework.Testing
étape 2
Ensuite créer une classe comme ceci:
étape 3
Maintenant, vous pouvez créer des simulacres super facilement:
Et ensuite utiliser votre maquette:
Article complet: http://www.22bugs.co/post/Mocking-DbContext/
Basé sur cette MSDN article, j'ai créé mes propres bibliothèques de se moquer de
DbContext
etDbSet
:À la fois disponible sur NuGet et GitHub.
La raison pour laquelle j'ai créé ces bibliothèques est parce que je voulais imiter la
SaveChanges
comportement, jeter unDbUpdateException
lors de l'insertion de modèles avec la même clé primaire et support multi-colonne/incrémentation automatique des clés primaires dans les modèles.En outre, puisque les deux
DbSetMock
etDbContextMock
hériter deMock<DbSet>
etMock<DbContext
, vous pouvez utiliser toutes les fonctionnalités de la Moq cadre.À côté de Moq, il est également NSubstitute mise en œuvre.
Utilisation avec le Moq version ressemble à ceci:
IDbSetMock
. Pour l'EF de Base,Include
est une méthode d'extension qui transmettra au fournisseur. Dans les deux cas, aussi longtemps que votre initialEntities comprennent, en fait, les données imbriquées, votre test doit réussir.Je suis en retard, mais trouvé cet article utile: Test avec InMemory MSDN (Docs).
Il explique comment utiliser une mémoire DB contexte (ce qui n'est pas une base de données) avec l'avantage de très peu de codage et la possibilité de réellement tester votre
DBContext
mise en œuvre.