Victor Grazi
Victor Grazi

Reputation: 16490

PowerMockito not obeying when.thenReturn

I am using PowerMockito to verify the number of calls on a private method: loadProperties(). I also have that method stubbed to return a pre-defined value.

Even though I have the method stubbed, the real implementation is being called, and throwing a NullPointerException, since its dependency (the "loader" variable, see snippet below) is not defined (nor should it be) for this test.

As an experiment, I changed the method to be public, and then it works fine!

I am thinking it is a bug in PowerMockito, but I have been wrong about more certain things than this!

Here is the code

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.util.HashMap;
import java.util.Map;

import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.times;
import static org.powermock.api.mockito.PowerMockito.mock;
import static org.powermock.api.mockito.PowerMockito.when;


@RunWith(PowerMockRunner.class)
@PrepareForTest({DArgumentsLoader.class})
public class TestConfig {
 @Test
 public void testGetPropertyMapCalledOnce() throws Exception {
     Config configMock = mock(Config.class);
     Map<String, String> testMap = new HashMap<String, String>();
     testMap.put("xx", "xx");
     when(configMock, "loadProperties").thenReturn(testMap);

     when(configMock.getString(anyString(), anyString())).thenCallRealMethod();
     // call it twice
     configMock.getString("xx", "yy");
     configMock.getString("xx", "yy");
     // verify loadProperties was only called once
     PowerMockito.verifyPrivate(configMock, times(1)).invoke("loadProperties");
 }
}

Just to clarify, the Config class looks like this

private Map<String, String> loadProperties() throws IOException, HttpException {
    return loader.loadProperties();
}

public String getString(String key, final String defaultValue) {
    String value = getPropertyMap().get(key);
    if(value != null) {
        return value;
    } else {
        return defaultValue;
    }
}

private Map<String, String> getPropertyMap() throws LoadException {
    if(propertyMap == null) {
        propertyMap = loadProperties();
    }
    return propertyMap;
}

The loadProperties() method should not be called at all, in view of the fact that the tester says

when(configMock, "loadProperties").thenReturn(testMap);

But it is being called, and it is throwing a NullPointerException. Is that a bug or a feature?

Upvotes: 1

Views: 998

Answers (1)

Mureinik
Mureinik

Reputation: 311228

You are not preparing the Config class for mocking, so PowerMock cannot handle it. Just add it to the @PrepareForTest annotation, and you should be fine:

@PrepareForTest({Config.class, DArgumentsLoader.class})

Upvotes: 1

Related Questions