Search code examples
androidmockingrobolectricpowermockpowermockito

Powermock keeps returning me a null object not a mock


So I am looking at the mocking objects in a test. However the following test will return npe when " Mockito.when(mock.getName()" portion of code is executed, thats because the mock object is returned as null.

package com.example.activity;

import com.example.BuildConfig;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.rule.PowerMockRule;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;

import static org.junit.Assert.assertTrue;

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
@PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
@PrepareForTest(Static.class)
public class DeckardActivityTest {

    @Rule
    public PowerMockRule rule = new PowerMockRule();

    @Mock
    public ToBeMocked mock;

    @Test
    public void testSomething() throws Exception {
        assertTrue(Robolectric.buildActivity(DeckardActivity.class).create().get() != null);
    }

    @Test
    public void testStaticMocking() {
        PowerMockito.mockStatic(Static.class);
        Mockito.when(Static.staticMethod()).thenReturn(mock);
        Mockito.when(mock.getName()).thenReturn("Mock");
        assertTrue(Static.getResp().equals("Mock"));
    }
}

and the simple class we are testing

package com.example.activity;

public class Static {

    private static ToBeMocked toBeMocked;

    public static ToBeMocked staticMethod() {
        toBeMocked = new ToBeMocked();
       return toBeMocked;
    }

    public static String getResp(){
        return toBeMocked.getName();
    }
}

So my understanding must be wrong. What I would like to do is mock out the ToBeMocked class dependency give it and tell the mock object how to respond when getName method is called on it.

Can some one help me as to why this is going wrong or point out what I must have misunderstood


Solution

  • Yes, you understand it wrong. I mean you have misunderstanding how mocks work.

    Your method getResp (in example) uses internal states which will not be set at all, because after you call PowerMockito.mockStatic(Static.class); all calls of static methods of the Static.class will be intercepted. So the code:

    toBeMocked = new ToBeMocked();
    return toBeMocked;
    

    never is called.

    If the getResp uses the staticMethod() then you code will work.

    public static String getResp(){
        return staticMethod().getName();
    }
    

    So you have two option to resolve your issue:

    • refactor your code as I pointed
    • use mock constructor to mock toBeMocked = new ToBeMocked();