Я просто озадачен этим (Mockito 1.10):Mockito - какие правила управляют инъекциями насмешек подобных классов коллекций?
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock
private Collection<IndexableField> mockedFieldsFromRetrievedDocument;
@Spy
@InjectMocks
private IndexManager injectedSpyIM = new IndexManager();
@Test
public void numberOfLDocsShouldBePrintedOutWithEachHitLine() throws Exception{
LOGGER.info(String.format("# A: %d", mockedFieldsFromRetrievedDocument.hashCode()));
LOGGER.info(String.format("# fFRD %s", injectedSpyIM.getFFRD()));
Естественно, существует метод getFFRD
в IndexManager
, который возвращает частное поле,
private Collection<IndexableField> fieldsFromRetrievedDocument;
Существует также другое частное поле IndexManager
:
private Collection<Closeable> closeableComponents;
Первая зафиксированная строка дает правильный хэш-код.
Последняя строка говорит
# fFRD Null
Когда я потом пошел и исследовал значение closeableComponents
я обнаружил, что его хэш-код был именно нагнетаемой макете Collection
.
Затем я попытался обменивать позиции деклараций этих полей в IndexManager
: без изменений.
Оказывается, что @Mock
линия здесь 1) полностью игнорируя общий класс и 2) запирается на к Collection<Closeable>
в предпочтении к другим причинам я не понимаю ...
НЕМНОГО позже
Вау, сумасшедшие вещи: я просто изменил название поля closeableComponents
к xcloseableComponents
. Теперь издеваемое поле действительно делает то, что я хочу, т. Е. Издеваясь над полем fieldsFromRetrievedDocument
.
Мой условный вывод, естественно, заключается в том, что Mockito использует первое имя поля типа Collection<anything>
, которое оно находит ... в алфавитном порядке! Предположительно, один и тот же процесс отбора применяется к другим случаям, когда имеется более одного поля типа «тот же». Просто безуспешно смотрел на него: кто-нибудь знает, где это где-то документировано?
еще позже
Следуя совету Джефф Боуман я изменил вещи, как так:
@Mock(name="fieldsFromRetrievedDocument")
private Collection<?> mockedFieldsFromRetrievedDocument;
... это точное написание, при правильном случае поля в классе , Но он все еще вводил неправильный Collection<?>
в качестве издевки. Затем ...
Я изменил с Mockito с 1 по 10, 2.3.0: проблема решена! Предостерегающий рассказ о том, что атрибут name
полностью задокументирован в Javadoc API 1.10 ...!
Еще раз спасибо. В следующий раз я попробовал дать тестовому классу инъецированный макет с тем же именем, что и фактическое поле в CUT. Я не думал, что это сработает ... и я был прав! Но теперь я знаю, что аннотация '@ Mock' имеет необязательный атрибут« name ». У меня есть над чем работать. Возможно, вы могли подумать, что, столкнувшись с двумя полями того же типа, их фактические имена можно сравнить с их действительными именами, поскольку отражение используется, если '' mockedFoo '.containsIgnoringCase ("foo") ' то предполагается, что 'mockedFoo' стоит за' foo', при отсутствии каких-либо двусмысленностей. Кажется, нет! –
PS мысль № 2: получение дженериков путем отражения: некоторые мысли здесь: http://stackoverflow.com/questions/1901164/get-type-of-a-generic-parameter-in-java-with-reflection. Не могли ли Mockito попробовать sthg в этом направлении? –
@mike Пожалуйста, ознакомьтесь с тем, как «это невозможно сделать» - это правильный ответ на этот вопрос. Самое близкое, что вы можете получить (это то, на что ссылаются большинство ответов), - это то, что для 'класса B extends A' или 'new A () {}' вы можете отразить A и T из иерархии _type_. Существует способ получить информацию о родовом типе [из определения поля] (http://stackoverflow.com/q/1868333/1426891), но с учетом переменных типа типа вы просите Mockito получить очень умный за счет читаемости и четкости рамок. –