Не рекомендуется ли использовать @Spy и @InjectMocks в одном поле?
В проекте, над которым я сейчас работаю,
Я часто вижу @Spy
и @InjectMocks
, используемые вместе на поле.
Я никогда не видел такого в каких-либо учебниках или других ресурсах.
Я погуглил об этой конкретной комбинации, но не сделал
найти что-нибудь еще, кроме этой темы на GitHub:
https://github.com/mockito/mockito/issues/169
Что заставляет меня думать, что мы используем его странным образом.
Примечание: причина, по которой я думаю использовать обе аннотации вместе
имеет смысл иногда потому, что если вы используете только @InjectMocks
Mockito пытается создать экземпляр класса с помощью конструктора без аргументов.
Если у вас нет конструктора без аргументов и вы добавили @Spy
, вы можете использовать объект, не нуждаясь в пустом конструкторе.
Редактировать: еще одно важное использование, что вы можете только методы заглушки
если вы просто используете обе аннотации.
Ответы
Ответ 1
Нередко и, возможно, неуместно использовать @Spy и @InjectMocks вместе.
@InjectMocks работает как своего рода инъекция зависимостей для тестируемой системы: если у вас есть тест, который определяет @Mock или @Spy нужного типа, Mockito будет инициализировать любые поля в вашем @InjectMocks экземпляр с этими полями. Это может быть удобно, если вы еще не структурировали свой системный тест для инъекции зависимостей (или если вы используете инфраструктуру DI, которая делает инъекцию на местах), и вы хотите заменить эти зависимости на mocks. Это могут быть довольно хрупкие, не имеющие аналогов поля будут игнорироваться и будут оставаться null
, если они не установлены в инициализаторе, но остаются достойной аннотацией для вашей тестируемой системы.
@Spy, например @Mock, предназначен для настройки тестовых удвоений; вы должны использовать его, когда у вас есть сотрудник, которого вы хотите заглушить или проверить. Обратите внимание, что @Spy и @Mock всегда предназначены для зависимостей, а не для вашей тестируемой системы.
В идеале, у вас не должно быть класса, который выполняет обе роли в одном и том же тесте, иначе вы можете написать тест, который тщательно проверяет поведение, которое вы опустили, а не фактическое производственное поведение. В любом случае будет сложнее рассказать, что касается теста, в сравнении с поведением, которое вы пропустили.
Конечно, это может не примениться, если вы пытаетесь использовать Mockito для тестирования одного метода изолированно, и вы хотите заглушать вызовы одним методом во время тестирования другого. Однако это также может свидетельствовать о том, что ваш класс нарушает принцип единой ответственности и что вы должны разбить класс на несколько независимых классов, которые работают вместе. Затем в вашем тесте вы можете разрешить экземплярам иметь ровно одну роль и никогда не нуждаться в обеих аннотациях сразу.
Ответ 2
Каждая аннотация имеет разные цели, и они явно не наступают друг на друга, пока вам нужно использовать частичные макеты. (известный как метод, связанный с заглушкой, который уже был проверен и/или заслуживает доверия)
Например, у вас есть класс для тестирования, в котором есть инъекция (и) зависимостей, которые не обязательно должны быть реальными, поэтому вы хотите использовать @InjectMocks. Кроме того, метод, который вы тестируете, вызывает другой метод внутри, который уже был где-то протестирован, или он вызывает внешнюю ссылку, которая также была протестирована, скорее всего, независимо. Таким образом, вам не нужно беспокоиться о том, чтобы тестировать один и тот же метод более одного раза, и на ваш тестовый код не должно повлиять изменение реализации вне области видимости в любое время в будущем.
Только пары @Mock & @Spy или @Mock & @InjectMocks не имеют смысла.
Ответ 3
Извините, я не понял 100%, почему пара @Mock & @InjectMocks не имеет смысла. В моих тестах у меня есть класс @InjectMocks, который я хочу протестировать, а затем все методы @Mock, и тест работает правильно