Проблема насмешки, публичная функция, вызывающая частную функцию

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

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

Я использую Rhino Mocks.

Спасибо за любую помощь:)

5 ответов

Если вы поместите функциональность, которая делает чтение файла в класс, например

FileReader : IFileReader

Затем передайте IFileReader как аргумент конструктору. Вы можете тогда посмеяться над этим

Убедитесь, что вы согласны с самим собой, если это услуга или субъект предпринимательства.

Служба обычно признается в том, что она использует набор бизнес-объектов для выполнения некоторой задачи и сама не поддерживает надежные данные.

Бизнес-объект - это единица в вашей проблемной области, которую вы хотели бы сохранить концептуально.

Если вы обнаружите, что это сервис, вы должны каким-то образом внедрить зависимость при создании сервиса. Обычно это может иметь конструктор, подобный этому: public MyService(IFileObject)

При построении из main: var service = new MyService(MyRealFile)

При построении из тестовой настройки: var service = new MyService(MyMockedFiled)

Если вы обнаружите, что то, что вы тестируете, на самом деле является бизнес-сущностью, тогда вам следует избегать предоставления сущности зависимости. Обычно вы делаете шаг назад и создаете класс Service между вами и бизнес-объектом. Служба явно передает бизнес-субъекту все необходимые данные. В вашем случае это означает, что служба предоставляет объекту все, что он должен изучить, читая файл.

Сервис, таким образом, является зависимым от файловой системы и может даже использовать другой (выделенный) бизнес-объект для чтения файлов для чтения файла. Вам бы никогда не хотелось, чтобы бизнес-объекты делали мошеннические вызовы зависимостей, если вы используете их где-то еще в системе. Их код становится связанным с контекстом, чего вы хотели бы избежать. Бизнес должен быть быстрым, дискретным, определенным и отзывчивым.

Ваш юнит-тест должен быть в сервисе, который может получить зависимость путем инъекции. Если вы обнаружите, что проводите модульное тестирование бизнес-объекта, вам не хватает уровня обслуживания.

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

template <class FileReader>
class SomeClass
{
  private: void doSomething()
  {
    FileReader fileReader;
    // Do something
  }
};

Другой способ - передать метод в конструктор SomeClass, который возвращает реализацию FileReader. Это можно использовать во всем классе, аналогично тому, как используется шаблон, но при этом вы все равно получите свой MockFileReader из IFileReader.

Проблема с любым из них состоит в том, что модульные тесты не могут быть выполнены в FileReader, потому что нет доступа к нему из SomeClass.

Приведенный выше код - C++, но я знаю, что оба метода выполнимы с C#.

Вытяните файловую зависимость и передайте интерфейс IFileSomething в конструкторе. Затем посмеяться над IFileSomething и установить ожидание.

Спасибо за ответы, мой файл cookie был удален. Я использовал первый ответ и немного изменил код. Работает хорошо:)

Другие вопросы по тегам