Difference between spy and stub in Mockito framework
I will show the difference with code directly and then i will add my comment.
@Service
public class CelalService {public String getName() {
return "Celal";
}
public String getSurname() {
return "Kartal";
}
}
@Service
public class CelalManager {
private final CelalService celalService;
public CelalManager(CelalService celalService) {
this.celalService = celalService;
}
public String getName() {
return celalService.getName();
}
public String getSurname() {
return celalService.getSurname();
}
}
Firstly, i will use spy for mocking.
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import org.mockito.junit.jupiter.MockitoExtension;@ExtendWith(MockitoExtension.class)
public class CelalTest { @Spy
CelalService celalService; @InjectMocks
CelalManager celalManager;@Test
public void spyTest() {
when(celalService.getName()).thenReturn("mockCelal");
System.out.println(celalManager.getName());
System.out.println(celalManager.getSurname()); verify(celalService, times(1)).getName();
verify(celalService, times(1)).getSurname(); }
}
Output:
mockCelal
Kartal
Spy is copy of the mock class and you can change result of some methods for a different result or you can use the default return. For example, we changed celalManager.getName() return value for different value but we didn't change celalManager.getSurname() return value and we used default value…
In short, Spy provides us with a partial mock.
With Spy, you can think your CelalService class behaves as below;
public class CelalService {public String getName() {
return "mockCelal";
}
public String getSurname() {
return "Kartal";
}
}
Now, let’s look for stubbing.
import static org.mockito.Mockito.when;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;@ExtendWith(MockitoExtension.class)
public class CelalTest {
@Mock
CelalService celalService; @InjectMocks
CelalManager celalManager;@Test
public void test() {
when(celalService.getName()).thenReturn("mockCelal");
System.out.println(celalManager.getName());
System.out.println(celalManager.getSurname()); verify(celalService, times(1)).getName();
verify(celalService, times(1)).getSurname();
}
}
Output:
mockCelal
null
With Stub , all methods of the mock class are set to automatically return null. You can set a different return if you want via when-thenReturn( like when(celalService.getName()).thenReturn(“mockCelal”);)
In short, Stub provides us with an exact mock.
With Stub, you can think your CelalService class behaves as below;
public class CelalService {public String getName() {
return "mockCelal";
}
public String getSurname() {
return null;
}
}