I want to mock an inherited protected method. I can't call this method directly from java code as it is inherited from class that in another package. I can't find a way to specify this method to stub in in when(...)
package a;
public class A() {
protected int m() {}
}
package b;
public class B extends a.A {
// this class currently does not override m method from a.A
public asd() {}
}
// test
package b;
class BTest {
@Test
public void testClass() {
B instance = PowerMockito.spy(new B());
PowerMockito.when(instance, <specify a method m>).thenReturn(123);
//PowerMockito.when(instance.m()).thenReturn(123); -- obviously does not work
}
}
I looked at PowerMockito.when
overrides and this seems that they are all for private methods only!
How to specify protected method?
For Mockito, there is no direct support to mock private and static methods. In order to test private methods, you will need to refactor the code to change the access to protected (or package) and you will have to avoid static/final methods.
To test a protected method using junit and mockito, in the test class (the class used to test the method), create a “child class” that extends the protagonist class and merely overrides the protagonist method to make it public so as to give access to the method to the test class, and then write tests against this child ...
In most cases, you do not want to write tests for non-public methods, because that would make the tests dependent on the internal implementation of a class. But there are always exceptions.
Mocking is done when you invoke methods of a class that has external communication like database calls or rest calls. Through mocking you can explicitly define the return value of methods without actually executing the steps of the method.
Nutshell: Can't always use when
to stub spies; use doReturn
.
Assuming static imports of spy
and doReturn
(both PowerMockito
):
@RunWith(PowerMockRunner.class)
@PrepareForTest(B.class)
public class BTest {
@Test public void testClass() throws Exception {
B b = spy(new B());
doReturn(42).when(b, "m");
b.asd();
}
}
You could also @PrepareForTest(A.class)
and set up the doReturn
on when(a, "m")
. Which makes more sense depends on the actual test.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With