Тестируемый модуль: Impl или интерфейс?JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Тестируемый модуль: Impl или интерфейс?

Сообщение Anonymous »


Предположим, у меня есть интерфейс и класс реализации, который его реализует, и я хочу написать для этого модульный тест. Что мне следует протестировать: интерфейс или Impl?

Вот пример:

публичный интерфейс HelloInterface { общественная недействительность SayHello(); } публичный класс HelloInterfaceImpl реализует HelloInterface { частная цель PrintStream = System.out; @Override общественный недействительный SayHello () { target.print("Привет, мир"); } общественная недействительность setTarget (цель PrintStream) { this.target = цель; } } Итак, у меня есть HelloInterface и HelloInterfaceImpl, которые его реализуют. Что такое интерфейс тестируемого модуля или Impl?

Я думаю, это должен быть HelloInterface. Рассмотрим следующий эскиз теста JUnit:

публичный класс HelloInterfaceTest { частный HelloInterface привет; @До общественный недействительный setUp () { привет = новый HelloInterfaceImpl (); } @Тест общественный недействительный testDefaultBehaviourEndsNormally () { привет.sayHello(); // здесь нет NullPointerException } @Тест public void testCheckHelloWorld() выдает исключение { ByteArrayOutputStream out = новый ByteArrayOutputStream (); Цель PrintStream = новый PrintStream (выход); PrivilegedAccessor.setValue(привет, «цель», цель); //Вы можете использовать ReflectionTestUtils вместо PrivilegedAccessor //действительно это ДИ //((HelloInterfaceImpl)hi).setTarget(target); привет.sayHello(); Строковый результат = out.toString(); AssertEquals("Привет, мир", результат); } } На самом деле я закомментировал основную строку.

((HelloInterfaceImpl)hi).setTarget(target);

Метод setTarget() не является частью моего публичного интерфейса, поэтому я не хочу случайно вызывать его. Если я действительно хочу позвонить, мне следует потратить немного времени и подумать об этом. Например, это помогает мне понять, что на самом деле я пытаюсь сделать внедрение зависимостей. Это открывает для меня целый мир новых возможностей. Я могу использовать какой-либо существующий механизм внедрения зависимостей (например, Spring), я могу смоделировать его самостоятельно, как я это делал на самом деле в своем коде, или применить совершенно другой подход. Присмотритесь, подготовка PrintSream была не такой простой, может быть, вместо этого мне стоит использовать макет объекта?

РЕДАКТИРОВАТЬ: Я думаю, мне следует всегда сосредоточиться на интерфейсе. С моей точки зрения, setTarget() не является частью «контракта» класса impl, он служит уловкой для внедрения зависимостей. Я думаю, что любой общедоступный метод класса Impl следует рассматривать как частный с точки зрения тестирования. Однако это не значит, что я игнорирую детали реализации.

См. также «Должны ли частные/защищенные методы проходить модульное тестирование?»

EDIT-2 В случае нескольких реализаций\нескольких интерфейсов я бы протестировал все реализации, но когда я объявляю переменную в своем методе setUp() Я бы определенно использовал интерфейс.
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»