126 votes

Mocking d'objets avec Moq lorsque le constructeur a des paramètres

J'ai un objet que j'essaie de simuler en utilisant moq. Le constructeur de l'objet a des paramètres obligatoires :

public class CustomerSyncEngine {
    public CustomerSyncEngine(ILoggingProvider loggingProvider, 
                              ICrmProvider crmProvider, 
                              ICacheProvider cacheProvider) { ... }
}

Maintenant, j'essaie de créer le mock pour cet objet en utilisant la syntaxe de moq v3 "setup" ou v4 "Mock.Of" mais je n'arrive pas à comprendre... tout ce que j'essaie ne se valide pas. Voici ce que j'ai jusqu'à présent, mais la dernière ligne me donne un objet réel, pas le mock. La raison pour laquelle je fais cela est que j'ai des méthodes sur le CustomerSyncEngine dont je veux vérifier qu'elles sont appelées...

// setup
var mockCrm = Mock.Of<ICrmProvider>(x => x.GetPickLists() == crmPickLists);
var mockCache = Mock.Of<ICacheProvider>(x => x.GetPickLists() == cachePickLists);
var mockLogger = Mock.Of<ILoggingProvider>();

// need to mock the following, not create a real class like this...
var syncEngine = new CustomerSyncEngine(mockLogger, mockCrm, mockCache);

111voto

Suhas Points 1282

Remplacer la dernière ligne par

var syncEngine = new Mock<CustomerSyncEngine>(mockLogger, mockCrm, mockCache).Object;

et cela devrait fonctionner

39voto

Chamkila Points 1355

La dernière ligne vous donne une instance réelle parce que vous utilisez le mot-clé new, et non pas le mocking CustomerSyncEngine.

Vous devez utiliser Mock.Of<CustomerSyncEngine>()

Le seul problème avec les types concrets est que le Moq a besoin d'un constructeur public par défaut (sans paramètres) OU que vous devez créer le Moq en spécifiant l'argument du constructeur. http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html

La meilleure chose à faire est de faire un clic droit sur votre classe et de choisir Extraire l'interface.

0voto

Dave Black Points 1396

Il devrait l'être : var syncEngine = new Mock<CustomerSyncEngine>(mockLogger.Object, mockCrm.Object, mockCache.Object).Object;

Vous devez passer les objets qui sont simulés au constructeur, et non les simulacres eux-mêmes. TLDR ; Utilisez la propriété Object sur les objets fantaisie.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X