web-dev-qa-db-fra.com

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

J'essaie de me moquer d'un objet en utilisant moq. Le constructeur de l'objet a les paramètres requis:

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

Maintenant, j'essaie de créer la maquette pour cet objet en utilisant soit la syntaxe mo3 "setup" ou v4 "Mock.Of", mais je n'arrive pas à comprendre ... tout ce que j'essaie ne valide pas. Voici ce que j'ai jusqu'à présent, mais la dernière ligne me donne un objet réel, pas la maquette. La raison pour laquelle je fais cela est parce que j'ai des méthodes sur le CustomerSyncEngine que je veux vérifier 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);
82
Andrew Connell

La dernière ligne vous donne une instance réelle, car vous utilisez le nouveau mot-clé et ne vous moquez pas de CustomerSyncEngine.

Vous devriez utiliser Mock.Of<CustomerSyncEngine>()

Le seul problème avec les types concrets de Mocking est que Moq aurait besoin d'un constructeur par défaut public (sans paramètre) OR vous devez créer le Moq avec la spécification de constructeur arg. http: // www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html

La meilleure chose à faire serait de faire un clic droit sur votre classe et de choisir l'interface d'extraction.

31
Raghu

Changer la dernière ligne en

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

et ça devrait marcher

58
Suhas