2015-01-29 2 views
3

Я новичок в Moq, и я просто смотрел видеоролик с множественным количеством изображений на Moqing, поэтому я чувствовал себя уверенным, чтобы пойти и написать несколько тестов. Я имею базовый класс, скажем, лист, который реализует интерфейс ISheet. Лист является базовым классом для страниц:Moq базовая функция класса из производного класса

abstract class Sheet: ISheet 
{ 
    public virtual void CreateSheet() // Defined in ISheet 
    { 
    } 
    public virtual void BuildSheet() // Defined in ISheet 
    { 
    } 
    //and some abstract methods, etc. 
} 

public class Page : Sheet 
{ 
    public override void CreateSheet() 
    { 
     BuildSheet(); // Base class implementation 
    } 
} 

Я перекрыла один из методов из базового класса, который CreateSheet(), но я хочу, чтобы проверить, что метод BuildSheet() в базовом классе вызывается из моего производного класса:

Таким образом, в моем тестовом классе, я MOq в SUT вместо интерфейса

var MockSheet = new Moq<Page>(); 

вызова метода:

var actual = MockSheet.Object.CreateSheet(); 

Затем проверьте

MockSheet.Verify(x => x.BuildSheet(), Times.AtLeastOnce); 

Вместо этого я получаю MockException «Ожидаемую Инвокацию на макете, по крайней мере один раз, но никогда не был выполнен. Метод CreateSheet никогда не вызывается. Если изменить его CreateSheet метод:

public void CreateDocSheet() // removed override 
{ 
    BuildSheet() // base classses implementation 
} 

И в тестовый звонок:

var actual = MockSheet.Object.CreateDocSheet(); 

Он работает. Я не понимаю, почему. Я считаю, что функционально, что это допустимый способ кодирования, у меня есть лист, который имеет 2 страницы, у меня есть интерфейс, который определяет все функции и свойства, которые должны быть реализованы, я реализую эти функции в базовом классе, но не все методы должны выполняться в производных классах, поэтому некоторые методы переопределяются, а некоторые используют реализацию базового класса. Пожалуйста, объясните, почему проблема заключается в использовании переопределенной версии функции?

ответ

6

Если вы изменяете

var MockSheet = new Moq<Page>(); 

в

var MockSheet = new Moq<Page> { CallBase = true, }; 

ваш макет (который вы можете думать, как производный класс Page) будет вызывать реализацию из Page в собственном переопределения Ложная о CreateSheet ,

поведение по умолчанию (если вы не изменяете CallBase) для Moq переопределить каждый метод и свойство его можно, и использовать пустой реализации. Установка CallBase на true делает Moq вместо Page, как я уже сказал.

(Конечно, используйте MockSheet.Setup(x => x.CreateDocSheet()).Callback(() => { /* something */ }), если вы хотите CreateDocSheet сделать что-то нетривиальное.)

В случае, когда вы удалили модификатор virtual из CreateSheet, Moq больше не может переопределить или макет этот элемент. Подумайте об этом: как Мок «высмеивал» не виртуальный метод? Поэтому вызов полностью обходит класс Мока.

+0

Хотя все это хорошая и полезная информация, Moq не может проверить, что 'PageCreateSheet' вызывает реализацию' BuildSheet' Sheet, а не '' '' BuildSheet'. Moq способен записывать вызовы на свой собственный прокси-сервер для самого издевающегося объекта. –

+0

Спасибо, что сработало и спасибо за объяснение. Я думал, что должен быть способ протестировать реализацию базового класса из производного класса без необходимости писать новую функцию, которую я еще не планировал делать. – user3666407

7

Moq предназначен для имитации зависимостей или зависимостей тестируемой системы, чтобы вы могли выделить это из остальной части вашего приложения или внешних эффектов, а не для , заменяя вашей тестируемой системой. Это не тот инструмент, который вы пытаетесь сделать здесь.

Смежные вопросы