Подтвердить что ты не робот

Не рекомендуется ли использовать @Spy и @InjectMocks в одном поле?

В проекте, над которым я сейчас работаю, Я часто вижу @Spy и @InjectMocks, используемые вместе на поле. Я никогда не видел такого в каких-либо учебниках или других ресурсах. Я погуглил об этой конкретной комбинации, но не сделал найти что-нибудь еще, кроме этой темы на GitHub: https://github.com/mockito/mockito/issues/169

Что заставляет меня думать, что мы используем его странным образом.

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

Редактировать: еще одно важное использование, что вы можете только методы заглушки если вы просто используете обе аннотации.

4b9b3361

Ответ 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, и тест работает правильно