I have a class I want to test that has several external dependencies, and a couple internal methods. I would like to write a test for MethodA
, but not have Method A's internal call to MethodB
to actually exercise MethodB
. I'd like to mock/stub MethodB
and return something specific instead. Usually I'd use when/thenReturn
but it doesn't behave like I expect - it actually jumps into Method B while creating the mock itself.
MyService.java
@Service
public class MyService {
@Autowired
private ServiceA serviceA;
@Autowired
private ServiceB serviceB;
public SomeObject methodA() {
// some logic using serviceA.method and serviceB.method that creates "output"
SomeObject someObject = methodB(output);
return someObject;
}
public SomeObject methodB(SomeObject someObject) {
// deep mysteries done here to someObject
return someObject
}
}
MyServiceTest.java
public class MyServiceTest {
@Mock
private ServiceA serviceA;
@Mock
private ServiceB serviceB;
@InjectMocks
private MyService myService;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void methodATest() {
when(serviceA.method()).thenReturn(stuff);
when(serviceB.method()).thenReturn(otherStuff);
// here is what I would like to do
when(myService.methodB()).thenReturn(mockedSomeObject); //<- doesn't work
assertThat(myService.methodA().getSomeObjectProperty())
.isEqualTo("property");
}
}
I've looked at solutions that manually mock the MyService
class with Mockito.mock(MyService.class)
, but (as the above example is obviously contrived) my actual class has quite a few external dependencies and I'd prefer a solution that still allows me to mock the service using @Mock
for the @Autowired
dependencies and @InitMocks
for the class under test, unless it's simply not possible.
I've tried:
Mockito.doReturn(mockedSomeObject).when(myService.methodB(any(SomeObject.class));
but that also steps into MethodB when creating the mock for that method, which shouldn't be happening.
Thanks in advance for the help!
Try Adding @Spy to your InjectMocks and use the object to "expect" them in a slightly different syntax.
import org.mockito.Spy;
@InjectMocks
@Spy
private MyService myService;
And now mock the service call
Mockito.doReturn(mockedSomeObject).when(myService).methodB();
Also change the other mock call to this
Mockito.doReturn(stuff).when(serviceA).method();
Mockito.doReturn(otherStuff).when(serviceB).method();
You need to mark your object as Spy or explicitly create a Spy object for it using MyClass objA=null;
MyClass spy_objA=Powermockito.spy(objA)
doReturn(what_you_want).when(spy_objA).method()
Edit: Can find a similar question you may want to check How to mock another method in the same class which is being tested?
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