ericj
ericj

Reputation: 2291

How to stub a method of an class annotated with @InjectMocks?

Below MyDictionary.get method uses the injected map by calling map.get.

Just of curiosity I stubbed the MyDictionary.get method, like I always do with mocks and spies, so I overwrite the injection.

But this only works when MyDictionary.get indeed calls map.get. If map.get returns some string (the empty string here), the stub Mockito.when does not work. The behavior is as if it is not there. In the assert line, dictionary.get("key") equals the empty string. This is what I do not understand.

@RunWith(MockitoJUnitRunner.class)
public class MockitoTest {

    @Mock
    Map<String, String>map;

    @InjectMocks
    MyDictionary dictionary;

    @Test
    public void testMyDictionary(){
        Mockito.when(dictionary.get("key")).thenReturn("value");
        Assert.assertEquals("value", dictionary.get("key"));
    }

    private static class MyDictionary{
        private Map<String, String> map; 
        public String get(String key){
            return map.get(key);
// or,
            return "";
        }
    }
}

Upvotes: 5

Views: 6729

Answers (1)

Maciej Kowalski
Maciej Kowalski

Reputation: 26492

I am really surprised that you do not get a MissingMethodInvocationException which is thrown when you try to stub a method of an object not being a @Mock or a @Spy.

The dictionary instance is just a regular instance of a class here not proxied by Mockito (because of the fact that only @InjectMocks annotation is used).

Another surprise is that you do not get a null when the map.get is triggered as default return value for a String returning method is null.

Anyway..

If you want to stub methods of the `dictionary' instance you have to configure your test class as follows:

@InjectMocks
@Spy
MyDictionary dictionary;

@Test
public void testMyDictionary(){
    doReturn("value").when(dictionary).get("key);
    Assert.assertEquals("value", dictionary.get("key"));
}

Upvotes: 5

Related Questions