У меня есть объект, который я пытаюсь высмеять с помощью moq. У конструктора объекта есть обязательные параметры:
public class CustomerSyncEngine {
public CustomerSyncEngine(ILoggingProvider loggingProvider,
ICrmProvider crmProvider,
ICacheProvider cacheProvider) { ... }
}
Теперь я пытаюсь создать макет для этого объекта, используя синтаксис moq v3 «setup» или v4 «Mock.Of», но не могу понять этого ... все, что я пытаюсь, не проверяется. Вот что у меня есть до сих пор, но последняя строка дает мне реальный объект, а не макет. Причина, по которой я это делаю, состоит в том, что у меня есть методы в CustomerSyncEngine, которые я хочу проверить, вызываются ...
// 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);
Ответы:
Последняя строка дает вам реальный экземпляр, потому что вы используете ключевое слово new, а не имитируете CustomerSyncEngine.
Вы должны использовать
Mock.Of<CustomerSyncEngine>()
Единственная проблема с типами Mocking Concrete заключается в том, что для Moq потребуется общедоступный конструктор по умолчанию (без параметров) ИЛИ вам нужно создать Moq со спецификацией конструктора arg. http://www.mockobjects.com/2007/04/test-smell-mocking-concrete-classes.html
Лучше всего щелкнуть правой кнопкой мыши свой класс и выбрать «Извлечь интерфейс».
источник
CustomerSyncEngine
который используется толькоICrmProvider
с традиционными реализациями имитаций, которые должны быть предоставлены для всех трех интерфейсов, тогда как контейнер autmocking позволит вам предоставить только один.Измените последнюю строку на
и это должно работать
источник
new Mock<CustomerSyncEngine>(new object[]{mockLogger, mockCrm, mockCache}).Object;