I have a class which I would like to test with a public method that calls private one. I'd like to assume that private method works correctly. For example, I'd like something like doReturn....when...
. I found that there is possible solution using PowerMock , but this solution doesn't work for me. How It can be done? Did anybody have this problem?
I don't see a problem here. With the following code using the Mockito API, I managed to do just that :
public class CodeWithPrivateMethod {
public void meaningfulPublicApi() {
if (doTheGamble("Whatever", 1 << 3)) {
throw new RuntimeException("boom");
}
}
private boolean doTheGamble(String whatever, int binary) {
Random random = new Random(System.nanoTime());
boolean gamble = random.nextBoolean();
return gamble;
}
}
And here's the JUnit test :
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 static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.when;
import static org.powermock.api.support.membermodification.MemberMatcher.method;
@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {
@Test(expected = RuntimeException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
CodeWithPrivateMethod spy = PowerMockito.spy(new CodeWithPrivateMethod());
when(spy, method(CodeWithPrivateMethod.class, "doTheGamble", String.class, int.class))
.withArguments(anyString(), anyInt())
.thenReturn(true);
spy.meaningfulPublicApi();
}
}
A generic solution that will work with any testing framework ( if your class is non- final
) is to manually create your own mock.
This doesn't use any framework so its not as elegant but it will always work: even without PowerMock. Alternatively, you can use Mockito to do steps #2 & #3 for you, if you've done step #1 already.
To mock a private method directly, you'll need to use PowerMock as shown in the other answer .
For some reason Brice's answer is not working for me. I was able to manipulate it a bit to get it to work. It might just be because I have a newer version of PowerMock. I'm using 1.6.5.
import java.util.Random;
public class CodeWithPrivateMethod {
public void meaningfulPublicApi() {
if (doTheGamble("Whatever", 1 << 3)) {
throw new RuntimeException("boom");
}
}
private boolean doTheGamble(String whatever, int binary) {
Random random = new Random(System.nanoTime());
boolean gamble = random.nextBoolean();
return gamble;
}
}
The test class looks as follows:
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 static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.powermock.api.mockito.PowerMockito.doReturn;
@RunWith(PowerMockRunner.class)
@PrepareForTest(CodeWithPrivateMethod.class)
public class CodeWithPrivateMethodTest {
private CodeWithPrivateMethod classToTest;
@Test(expected = RuntimeException.class)
public void when_gambling_is_true_then_always_explode() throws Exception {
classToTest = PowerMockito.spy(classToTest);
doReturn(true).when(classToTest, "doTheGamble", anyString(), anyInt());
classToTest.meaningfulPublicApi();
}
}
i know a way ny which you can call you private function to test in mockito
@Test
public void commandEndHandlerTest() throws Exception
{
Method retryClientDetail_privateMethod =yourclass.class.getDeclaredMethod("Your_function_name",null);
retryClientDetail_privateMethod.setAccessible(true);
retryClientDetail_privateMethod.invoke(yourclass.class, null);
}
With no argument:
ourObject = PowerMockito.spy(new OurClass());
when(ourObject , "ourPrivateMethodName").thenReturn("mocked result");
With String
argument:
ourObject = PowerMockito.spy(new OurClass());
when(ourObject, method(OurClass.class, "ourPrivateMethodName", String.class))
.withArguments(anyString()).thenReturn("mocked result");
Something to Consider
Make sure the private function is calling another public function and you can proceed only mocking the public function.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.