Unit Testing- Mock Objects
|The unit tests has to be fast, so the feedback time will be less and encourage developers to run unit tests for every change they make to the system. Keeping the unit tests may not be possible in all cases like the code needs to interact with external systems such as database or a network resource.
One way to solve this problem is to use stubs in place of actual porduction objetcs and hard code the responce in the stub objects. The problem with the stubs is that you have to manage them and the production code should allow to inject the stub objects in place of the actual production object.
There is a better way to solve this problem – Mock objects. Mockito allows you use the mock objects , you can define reponce to different methods present in your target object based on the parmeters passed to that method.
List mockedList=mock(List); or @Mock List mockedList;
You can pass this mock object to your production code, where the real object is expeted. Mockito also has dependency injection tool , you can inject your mock object into the target object using @InjectMocks annotation.
In the following example we see how to use mocks. The code needs get a user details given user name from a remote server.
The unit test code tests, if the returned User object user name matches with the given user name. Full code is available here. In the test we are using Mock Http object instead of real one, the mock object will be injected into the userProfileLoader when you call initMocks method
public class UserProfileLoaderTest { @Mock private Http http; @InjectMocks private UserProfileLoader userProfileLoader; @Before public void createLoader(){ userProfileLoader=new UserProfileLoader(); MockitoAnnotations.initMocks(this); } @Test public void getUserLoadsUserProfile() { when(http.get(contains("jUnit"))).thenReturn("jUnit"); UserProfile userProfile=userProfileLoader.getUser("jUnit"); assertThat(userProfile.getUserName(),equalTo("jUnit")); } }