Luciano Borges
Luciano Borges

Reputation: 827

How to spy chained functions?

I have a structure like the code below:

public class MyClass {
   private A myA;

   public callSomeMethod() {}
}

public class A {
   private B myB;
   // getter and setter
}

public class B {
  private BigDecimal C;
  // getter and setter
}

And in my tests I have something like that:

public class MyClassTest {

@InjectMocks
private MyClass underTest = new MyClass ();

@Spy
private A a;

@Test
public void shouldPass() {

X x = new X();
x.setSomething(10);

// given
stubData();
doReturn(x).when(a).getB().getC(); // <-- Here I got the error

// when
MyClass myc = underTest.callSomeMethod();

// then
assertEquals(myc.getC, 10);
}

}

How to use doReturn to "mock" the value when I a chained methods (in the example: getC) is called?

Upvotes: 0

Views: 206

Answers (1)

Rob Spoor
Rob Spoor

Reputation: 9175

a may be a spy, but the result of its getB() method isn't. You'll need to set that up.

Something like this should work to get getB() to return a spy:

doAnswer(i -> spy(i.callRealMethod())).when(a).getB();

That returns a different spy each time getB() is called, so if that method always returns the same instance, you can cache it:

B b = spy(a.getB());
doReturn(b).when(a).getB();

You can put all of this in an @BeforeEach method so that you don't have to repeat this for every test.

Upvotes: 1

Related Questions