powermock / powermock

PowerMock is a Java framework that allows you to unit test code normally regarded as untestable.
Apache License 2.0
4.16k stars 586 forks source link

Mock does not take affect when mocking overload private method and call real method #964

Open huaronghao opened 5 years ago

huaronghao commented 5 years ago

When I mocking a overload private method, It does not take any affect. I found this may be effected by “Matchers.any(Class clazz)” can not passed by variable parameter, and then WhiteboxImpl.java on line 870 will always pick up last passed method. following is mycode:

package com.ehm.cost.service.impl;

public class ParamsClass {
}
package com.ehm.cost.service.impl;

import java.util.List;

public class TestOverload {

    public String CallOverload(ParamsClass paramsClass, List<ParamsClass> s) {
        return overload(paramsClass, s);
    }

    private String overload(List a, List<ParamsClass> b) {
        return "call real overloadSecond";
    }

    private String overload(ParamsClass a, List<ParamsClass> b) {
        return "call real overloadFirst";
    }
}
package com.ehm.cost.service.impl;

import org.assertj.core.util.Lists;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyListOf;

@RunWith(PowerMockRunner.class)
@PrepareForTest(TestOverload.class)
public class TestOverloadTest {
    @Spy
    @InjectMocks
    private TestOverload testOverload = new TestOverload();

    @Before
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void testCallOverload() throws Exception {
        PowerMockito.doReturn("call mock method").when(testOverload, "overload", any(ParamsClass.class), anyListOf(ParamsClass.class));
        String returnS = testOverload.CallOverload(new ParamsClass(), Lists.newArrayList());
        System.out.println(returnS);
    }
}

When I run test,the result is: call real overloadFirst but expect: call mock method

MenchieYoung commented 4 years ago

I guess I have the same issue, tried all possible solutions but still not solved. The solution I have tried includes but not limit to: https://stackoverflow.com/questions/38155092/powermockito-is-calling-the-method-when-i-use-doreturn-when https://stackoverflow.com/questions/14651138/powermock-mock-a-static-method-then-call-real-methods-on-all-other-statics https://stackoverflow.com/questions/35701457/mocked-private-method-is-called-instead-of-being-mocked