Как новичок в TDD, который только что столкнулся с этой ситуацией в первый раз, я обнаружил, что я получил «непроверяемые» внутренние классы в результате рефакторинга, и если я использую «чистый» подход TDD, мне интересно, если вы может закончить с внутренними классами любым другим способом.
Проблема в том, что, если одна или несколько ссылок сделаны на объект внешнего класса из внутреннего класса, этот конкретный рефакторинг часто нарушает один или несколько тестов. Причина этого довольно проста: ваш фиктивный объект, если spy
, на самом деле является оберткой вокруг реального объекта
MyClass myClass = spy( new MyClass() );
... но внутренние классы всегда будут ссылаться на реальный объект, поэтому часто бывает так, что попытка применить mock к myClass
не будет работать. Хуже того, даже без насмешек существует высокая вероятность того, что вещь рухнет совершенно и необъяснимым образом, просто если она будет заниматься своим обычным делом. Также помните, что ваш шпион не будет запускать настоящий метод конструктора для себя: многое может пойти не так.
Учитывая, что наша разработка наших тестов является инвестицией в качество, мне кажется, что было бы ужасно стыдно просто сказать: «Хорошо, я просто собираюсь отказаться от этого теста».
Я предлагаю два варианта:
если вы замените прямой доступ вашего внутреннего класса к полям внешнего класса методами получения / установки (которые могут быть private
, как ни странно), это будет означать, что это методы mock , которые будут использоваться ... и поля mock. Ваши существующие тесты должны затем пройти успешно.
другая возможность состоит в том, чтобы реорганизовать этот внутренний класс, чтобы сделать его автономным классом, экземпляр которого заменяет ваш внутренний класс, и перенести один или несколько тестовых методов в новый тестовый класс для этого нового класса. Затем вы столкнетесь с (простой) задачей подстроить вещи так, чтобы ссылки на объект внешнего класса были параметризованы (т.е. в 99% случаев переданы как параметр конструктора), а затем могли быть соответствующим образом смоделированы. Это не должно быть слишком сложно. Хотя вам может потребоваться добавить подходящие методы получения / установки для полей private
во внешнем классе и / или создать один или несколько его private
методов package-private
. С этого момента внутренний класс становится «черным ящиком» для тестирования внешнего класса.
При использовании любого из этих подходов вы не понесли потери качества.