2016-04-28 2 views
0

Mockito аннотаций @Spy или @InjectMocks не будут работать на интерфейсах:Хорошая практика использования реализации вместо интерфейса при тестировании с помощью Mockito?

public interface MyService() {} 

public class MyServiceImpl implements MyService {} 


@RunWith(MockitoJUnitRunner.class) 
public class MyServiceTest { 

    @Spy 
    @InjectMocks 
    private MyService myService; // won't work 

    @Mock 
    MyDao myDao; 

    // tests 
} 

Из документации на Spy (что-то похожее на @InjectMocks):

Поле аннотированный с @Spy может быть проинициализирована Mockito если в типе (даже закрытый) найден конструктор аргументов . Но Mockito не может создавать внутренние классы, локальные классы, аннотация классы и интерфейсы. Поле, аннотированное с помощью @Spy, может быть явно инициализировано в точке объявления. В качестве альтернативы, если вы не представили экземпляр, Mockito попытается найти нулевой аргумент конструктор (даже закрытый) и создать экземпляр для вас. Но Mockito не может создавать внутренние классы, локальные классы, абстрактные классы и интерфейсы .

Так что я понимаю, что я не могу использовать интерфейс для шпиона. Он работает, когда я использую фактический класс реализации при объявлении/инициализации интерфейса.

Какое из нижеприведенных решений было бы лучше всего решить эти проблемы?

Решение 1:

@InjectMocks 
    private MyService myService = new MyServiceImpl(); // Program against Interface 

Решение 2:

@Spy 
    @InjectMocks 
    private MyServiceImpl myService; // Program against implementation 

Мой вопрос, является ли это хорошая идея использовать решение 2, и пусть Mockito обрабатывать экземпляра (но это означает, объявляя реализацию вместо интерфейса) ИЛИ используйте решение 1 с интерфейсом и сами объявляйте реализацию.

+1

Но это [проблема XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Шпионаж на 'MyService' не имеет смысла, так как это интерфейс. Чего вы действительно хотите достичь здесь? – Tunaki

+1

Если вы хотите протестировать реализацию, почему вы ее шпионируете? – Tunaki

+0

Модульные тесты должны тестировать реализации, а не интерфейсы. Поэтому я не вижу проблемы с тестированием против реализации. Это особенно верно в тех случаях, когда вы используете шпион, поскольку вы манипулируете или проверяете определенные аспекты реализации. Как и в стороне, принцип всегда иметь интерфейс имеет ограниченную ценность с сегодняшними IDE и другими инструментами. Я отказался от использования внутренних интерфейсов в своих приложениях (за некоторыми исключениями), поскольку в большинстве случаев они не предоставляют ничего (кроме дополнительного файла для сохранения моего javadoc ..). – Tobb

ответ

0

Спасибо за все ответы ребята. Это мне очень помогло. Я сейчас закрою этот вопрос.

В принципе, я должен протестировать против реализации. Я также хочу обратиться к this question, который содержит более полезную информацию.

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