Firstly, you cannot test private methods with JUnit/Mockito out of the box.
Secondly, your naming is confusing: You say „B
having getB()
“ and then you call the parameter a
(for a.getB()
). B.getB()
is supposed to return a C
, not a B
, since getC()
is invoked on it then. And you say „C
having getC()
“ and also „nested methods“. Furthermore, D.getD()
doesn't return an object of type D
but a long
. I adapted all this according to what I thought you intended.
If you make your method in your class under test non-private it works as follows:
Surrounding classes for demonstration
class B {
C getC() {
return null;
}
}
class C {
D getD() {
return null;
}
}
interface D {
default long getLong() {
return -1;
}
}
class E extends G {
}
class F {
G getG() {
return new E();
}
}
class G {
}
Class under test
import static java.lang.System.out;
class Clazz {
static boolean isE( final Object o ) {
return o instanceof E;
}
F f;
boolean method( final B b, final String origin ) {
out.printf( "---- %s%nb=%s%n", origin, b );
out.printf( "long=%s, original: %s%nisE=%s, original: %s%n",
b != null ? String.valueOf( b.getC().getD().getLong() ) : "<not invoked>",
( new D() {} ).getLong(),
isE( f.getG() ), Clazz.isE( new F().getG() ) );
final boolean check = b != null
&& b.getC().getD().getLong() >= 0
&& ! isE( f.getG() );
out.printf( "check=%s%n", check );
return check;
}
}
Test class
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.openMocks;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
class ClazzTest {
@InjectMocks
Clazz clazz = new Clazz();
@Mock private B b;
@Mock private C c;
@Mock private D d;
@Spy private F f;
@BeforeEach
void beforeEach() {
openMocks( this );
}
@Test
void testMocked() {
when( b.getC() ).thenReturn( c );
when( c.getD() ).thenReturn( d );
when( d.getLong() ).thenReturn( 0 );
when( f.getG() ).thenReturn( new G() );
assertTrue( clazz.method( b, "mocked" ) );
assertFalse( clazz.method( null, "mocked" ) );
}
@Test
void testOriginal() {
assertFalse( clazz.method( null, "original" ) );
assertThrows( NullPointerException.class, () -> clazz.method( new B(), "original" ) );
System.out.println( "expected <NPE thrown>" );
}
}
Output
---- mocked
b=b
long=0, original: -1
isE=false, original: true
check=true
---- mocked
b=null
long=<not invoked>, original: -1
isE=false, original: true
check=false
---- original
b=null
long=<not invoked>, original: -1
isE=true, original: true
check=false
---- original
b=igb.so.B@8dfe921
<expected NPE thrown>