Mam obiekt, który próbuję udawać, używając moq. Konstruktor obiektu ma wymagane parametry:
public class CustomerSyncEngine {
public CustomerSyncEngine(ILoggingProvider loggingProvider,
ICrmProvider crmProvider,
ICacheProvider cacheProvider) { ... }
}
Teraz próbuję utworzyć makietę dla tego obiektu przy użyciu składni moq v3 „setup” lub v4 „Mock.Of”, ale nie mogę tego rozgryźć ... wszystko, co próbuję, nie jest sprawdzane. Oto, co mam do tej pory, ale ostatnia linijka daje mi prawdziwy przedmiot, a nie próbę. Powodem, dla którego to robię, jest to, że mam metody w CustomerSyncEngine, które chcę sprawdzić, są wywoływane ...
// 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);
Odpowiedzi:
Ostatnia linia daje ci prawdziwą instancję, ponieważ używasz nowego słowa kluczowego, a nie kpiny z CustomerSyncEngine.
Powinieneś użyć
Mock.Of<CustomerSyncEngine>()
Jedynym problemem z typami Mocking Concrete jest to, że Moq potrzebowałby publicznego konstruktora domyślnego (bez parametrów) LUB musisz utworzyć Moq ze specyfikacją arg konstruktora. http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html
Najlepszą rzeczą do zrobienia jest kliknięcie klasy prawym przyciskiem myszy i wybranie interfejsu Extract.
źródło
CustomerSyncEngine
taki sposób, żeICrmProvider
dla wszystkich trzech interfejsów muszą być dostępne tylko zastosowania z tradycyjnymi implementacjami mockowania, podczas gdy kontener autmockujący pozwoliłby na udostępnienie tylko jednego.Zmień ostatnią linię na
i powinno działać
źródło
new Mock<CustomerSyncEngine>(new object[]{mockLogger, mockCrm, mockCache}).Object;