MOQ - як знущатися над інтерфейсом, який потрібно передати на інший інтерфейс?


76

що я хочу зробити, це побудувати moq для I1 - це прекрасно ... однак під час тестуючого методу, який використовує цей макет, мені потрібно передати його в I2, щоб отримати доступ до деяких властивостей, які не I1

Interface I1 
{ int AProperty{get;set;}}

Interface I2
{int AnotherProperty{get;set;}}

У мене тоді є деякі предмети

Class O1 : I1 {}

і

Class O2 : O1 , I2 {}

проблема полягає в тому, що коли у мене є екземпляр об'єкта, що реалізує I2, я можу передати його на I1, щоб отримати доступ до методів, включених через цей інтерфейс. У коді це не проблема, і всякий знак працює належним чином.

Єдина проблема виникає при написанні модульного тесту для цього класу.

Інтерфейси також виставляють метод, який називається GetNewInstance, який повертає ініціалізований екземпляр реалізованого об'єкта, відлитого в інтерфейс IGetNewInstance ... я зазвичай можу знущатись над цим штрафом і змусити його повернути себе (і тому я продовжую працювати з макетним об'єктом).

однак при спробі передати цей повернутий об'єкт типу I2 в I1 результати нульового посилання - це має сенс, оскільки макетний об'єкт, що реалізує I2, не успадковує нічого, що успадковує I1.

питання полягає в тому, як я можу змусити об'єкт-імітатор успадкувати одночасно з обох I1 та I2?

Відповіді:


128

Наскільки я вас розумію, ви хочете створити макет, який реалізує два інтерфейси. З Moq це так просто:

var mock = new Mock<IFoo>(); // Creates a mock from IFoo
mock.As<IBar>(); // Adds IBar to the mock
mock.As<IBar>().Setup(m => m.BarMethod()).Returns(new object()); // For setups.

Тепер ви можете встановити очікування та використовувати свій макет, як зазвичай використовуєте об'єкт, що реалізує обидва IFooі IBar.

Для вашого GetNewInstanceметоду ви можете просто встановити очікування, яке повертає сам макет.


33
До речі, для тих, хто читає, коли ви виконуєте налаштування, вам потрібно використовувати макет. AS <IBAR> .Налаштування (......)
Джон Ніколас

3
Чудово, це чудово працює. Якщо вам потрібно зробити .Setup, ви можете зробити все в одному рядку, вам не потрібно спочатку робити As <> самостійно, ви можете просто зробити все в одному рядку.
gakera

Чи є спосіб зробити це налаштування як неінтерфейс?
Суб’єктивна реальність
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.