Spy Objects
[wp_ad_camp_5]
A Mockito spy allows us to create a spy object from a real object with similar behavior where each method can be stubbed out when needed. It is ideal for testing legacy code as you cannot invoke a few testing impediment methods from your code under test, and also, you cannot mock a class that needs to be tested. A spy can stub these impediments without mocking the code under test, stub nontestable methods so that other methods can be tested easily, and verify interactions between two real objects without the need of stubbing any of their methods. It is also known as ‘partial mocking’.
Spy object vs mock object
A mock object created via
1 | Mockito.mock(java.lang.Class<T> classToMock) |
is devoid of behavior defined for the class-to-mock. The following codes demonstrate this main difference.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | /** * Test the difference between spy and mock object in their behavior. * * Spy objects allow us to use real object; whereas mock do not and requires the behaviors to be stubbed out (e.g., * using Mockito.when(..)...()) */ @Test public void test_spy_vs_mock() { StudentBean searchCriteria = new StudentBean("111", "Karl SG"); spyServiceRequestObject.setStudentSearchCriteria(searchCriteria); StudentBean returnedBeanFromSpyObject = spyServiceRequestObject.getStudentSearchCriteria(); Assert.assertTrue(returnedBeanFromSpyObject != null); mockedServiceRequestObject.setStudentSearchCriteria(searchCriteria); /** * Returns null as there is no "real codes" in setStudentSearchCriteria(...) and getStudentSearchCriteria(). * * The behavior is undefined specially for getStudentSearchCriteria() * */ StudentBean returnedBeanFromMockedObject = mockedServiceRequestObject.getStudentSearchCriteria(); Assert.assertTrue(returnedBeanFromMockedObject == null); } |
Real and Spy objects are NOT one and the same
[wp_ad_camp_4]
Spy objects are created from real objects. Any changes to the spy object do not affect the real object it based itself on. Same goes for the real object. Any changes to it do not affect the spy object created based on it. Here are the codes to prove it.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | /** * Test spy and real objects are two different objects. They refer to the same object. Changes in spy object do not * affect the real object. * */ @Test public void test_spy_and_realobject_are_two_different_objects() { StudentBean searchCriteria = new StudentBean("111", "Karl SG"); spiedOnrealServiceRequestObject.setStudentSearchCriteria(searchCriteria); // Spy object does not have StudentBean object Assert.assertNull(this.spyServiceRequestObject.getStudentSearchCriteria()); } |
Download the codes
https://github.com/Turreta/mockito-spy-samples
[wp_ad_camp_3]