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 с интерфейсом и сами объявляйте реализацию.
Но это [проблема XY] (http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). Шпионаж на 'MyService' не имеет смысла, так как это интерфейс. Чего вы действительно хотите достичь здесь? – Tunaki
Если вы хотите протестировать реализацию, почему вы ее шпионируете? – Tunaki
Модульные тесты должны тестировать реализации, а не интерфейсы. Поэтому я не вижу проблемы с тестированием против реализации. Это особенно верно в тех случаях, когда вы используете шпион, поскольку вы манипулируете или проверяете определенные аспекты реализации. Как и в стороне, принцип всегда иметь интерфейс имеет ограниченную ценность с сегодняшними IDE и другими инструментами. Я отказался от использования внутренних интерфейсов в своих приложениях (за некоторыми исключениями), поскольку в большинстве случаев они не предоставляют ничего (кроме дополнительного файла для сохранения моего javadoc ..). – Tobb