===== JUnit with Mockito =====
^What^ Where^
|Fast Introduction into Assertions| [[http://www.vogella.com/articles/JUnit/article.html#usingjunit_asserts|vogella.com]] |
|Introduction into unit testing| [[http://tutorials.jenkov.com/java-unit-testing/index.html|tutorials.jenkov.com]] |
|Mockito documentation | [[http://docs.mockito.googlecode.com/hg/latest/org/mockito/Mockito.html|docs.mockito.googlecode.com/]]|
|Comparisson: Mocks and Stubs | [[http://martinfowler.com/articles/mocksArentStubs.html|http://martinfowler.com/articles/mocksArentStubs.html]] |
==== Fallpits ====
^ Fallpit^ Descr^
| Async. Tests| When doing jobs on the UI thread inside a test - look out, that the test do not return, before the async UI job gets a chance to be done.
@Test
public void test() {
... UI call ...
//let the UI Thread wait 1000 ms, before returning
long stopTimestampt = System.currentTimeMillis() + 1000;
while (System.currentTimeMillis() < stopTimestampt) {
Display.getDefault().readAndDispatch();
}
}
|
==== JUnit ====
==== Mockito ====
== Glossar ==
^What^ Where^
|Mock|imitate an Object, with all methods. On default mock-methods return null, false...|
|Stub|getting Mock's methods return something else, than default values.|
|Spy|spy at object, replace some original methods.|
== Basics ==
public class MyTest {
//1. FILL THE CONTEXT
//@Spy annotated fields are in context of Mockito and can be injected by @InjectMocks
@Spy
private PreferenceService service = new LocalPreferenceService();
//@Mock annotated fields are in context of Mockito and can be injected by @InjectMocks
@Mock(name = "service2")
private PreferenceService service2;
/**
* This is important not to put multiple Objects of same type into the context by @Spy and @Mock, or there will be an ambigous situation and none of them will be injected by Mockito.
*/
//2. TELL THE MOCKITO TO FILL THE @Inject ANNOTATED FIELDS INSIDE OF preferenceStoreDb BY @Spy AND @Mock ANNOTATED FIELDS FROM THIS TEST
@InjectMocks
private RemotePreferenceStore preferenceStoreDb = new RemotePreferenceStore();
//3. INIT THE @Mock @Spy ANNOTATED OBJECTS, INJECT THEM INTO @InjectMocks ANNOTATED OBJECTS
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
@Test
public void getDefaultDefaultTest() {
...
}
}
== Stub methods ==
The methods for mocked objects - can be forced to return some stuff.
/* Mock the preference lookup. It's methods will be empty and must be stubed. */
@Mock
PreferenceLookup preferenceLookup;
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
// stub methods, so that they return an empty list
List> showNotificationPreferences = new ArrayList<>();
Mockito.when(preferenceLookup.getValue(Mockito.any(ViewablePreference.class))).thenReturn(
showNotificationPreferences);
Mockito.when(preferenceLookup.getValue(Mockito.anyString())).thenReturn(showNotificationPreferences);
preferenceLookup.getValue(new ViewablePreference()); // return showNotificationPreferences now
preferenceLookup.getValue("test"); // return showNotificationPreferences now
== Test E4 Plugins ==
The biggest problem in testing e4 stuff - is in faking the e4 platform classes.
The usual approach is to create an **IEclipseContext**, fill it with mocks, inject the context into classes under test.
/* Create an Eclipse Context */
IEclipseContext eclipseContext = EclipseContextFactory.create();
/* Mock the preference lookup. It's methods will be empty and must be stubed. */
@Mock
PreferenceLookup preferenceLookup;
/* classes under test */
MixedMessaging mixedMessaging;
NotificationFactory notificationFactory;
@Before
public void initMocks() {
/* create all the Spy and Mock annotated objects */
MockitoAnnotations.initMocks(this);
/* stub methods, so that they return an empty list */
List> showNotificationPreferences = new ArrayList<>();
Mockito.when(preferenceLookup.getValue(Mockito.any(ViewablePreference.class))).thenReturn(
showNotificationPreferences);
Mockito.when(preferenceLookup.getValue(Mockito.anyString())).thenReturn(showNotificationPreferences);
preferenceLookup.getValue("test"); // return showNotificationPreferences now
/* add mocks to the Context */
eclipseContext.set(PreferenceLookup.class, preferenceLookup);
/* class under test 1 */
eclipseContext.set(MixedMessaging.class, mixedMessaging);
// class under test 2
NotificationServiceCreationFunction notificationServiceCreationFunction = new NotificationServiceCreationFunction();
notificationFactory = notificationServiceCreationFunction.compute(eclipseContext);
}
@Test
public void test() {
//test here
}