I'm just puzzled by this (Mockito 1.10):
@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() ));
Naturally enough, there is a method getFFRD
in IndexManager
which returns the private field
private Collection<IndexableField> fieldsFromRetrievedDocument;
There is also another private field in IndexManager
:
private Collection<Closeable> closeableComponents;
The first logged line gives you a valid hashcode.
The last line says
# fFRD null
When I then went and examined the value of closeableComponents
I found that its hashcode was indeed that of the injected mock Collection
.
I then tried swapping around the positions of the declarations of these fields in IndexManager
: no change.
It appears that the @Mock
line here is 1) totally ignoring the generic class and 2) latching on to the Collection<Closeable>
in preference to the other for reasons I don't understand...
a bit later
Wow, crazy stuff: I just changed the name of the field closeableComponents
to xcloseableComponents
. Now the mocked field is indeed doing what I want, i.e. mocking the field fieldsFromRetrievedDocument
.
My provisional conclusion, naturally enough, is that Mockito uses the first field name of type Collection<anything>
it finds ... in alphabetical order! Presumably the same selection process applies to other cases where there is more than one field of the "same" type. Just googled on this without success: does anyone know if this is documented somewhere?
later still
Following Jeff Bowman's advice I changed things like so:
@Mock(name="fieldsFromRetrievedDocument")
private Collection<?> mockedFieldsFromRetrievedDocument;
... this is the exact spelling, with correct case, of the field in the class. But it was still injecting the wrong Collection<?>
as the mock. Then...
I changed from Mockito 1.10 to the latest, 2.3.0: problem solved! A cautionary tale, in that the name
attribute is fully documented in the Javadoc API of 1.10...!