I'm new to Mockito and have been having trouble with stubbing. I wanted to test a method but stub one line of that method which is a call to another class's method. Based on the code below, I was expecting Optional.empty() but got Optional.of("str should not be null"). What am I doing wrong?
public class ClassA {
public String str;
public Optional<String> method1() {
if (str == null) {
return Optional.of("str should not be null");
}
return Optional.empty();
}
}
public class ClassB {
public String thing;
public Optional<String> method2() {
ClassA classA = new ClassA();
Optional<String> str2 = classA.method1();
if (str2.isPresent()) return str2;
if (thing == null) return Optional.of("thing should not be null");
return Optional.empty();
}
}
public class ClassBTest {
@Test
public void method1_test() {
ClassB classBSpy = spy(new ClassB());
ClassA classASpy = spy(new ClassA());
doReturn(Optional.empty()).when(classASpy).method1();
assertEquals(Optional.empty(), classBSpy.method2());
}
}
To make a stub of ClassA effective in ClaasB, you need a way to insert the Spy/Mock of CLassA into CLassB, i.e. through the constructor:
public class ClassB {
public String thing;
private ClassA classA = new ClassA();
public ClassB() {
super();
}
public ClassB(ClassA classA) {
super();
this.classA = classA;
}
public Optional<String> method2() {
Optional<String> str2 = classA.method1();
if (str2.isPresent()) return str2;
if (thing == null) return Optional.of("thing should not be null");
return Optional.empty();
}
}
public class ClassBTest {
@Test
public void method1_test() {
ClassA classASpy = spy(new ClassA());
ClassB classB = new ClassB(classASpy);
doReturn(Optional.empty()).when(classASpy).method1();
assertEquals(Optional.empty(), classB.method2());
}
}
But the test still fails since Optional.empty().isPresent()
is false
and thing
is awlays null
.