Auto-injection of mocks using Mockito with RoboGuice & Robolectric
Aren't you tired with manually defining Guice's AbstractModule class just to make RoboGuice inject your mocks instead of real implementations?
If so, try this JUnit4 runner:
MocksInjectingTestRunner.java
public class MocksInjectingTestRunner extends RobolectricRoboTestRunner {
public MyOwnTestRunner(Class<?> testClass) throws InitializationError {
super(testClass);
}
@Override
public void prepareTest(Object test) {
super.prepareTest(test);
MockitoAnnotations.initMocks(test);
try {
setupRoboguice(test, getListOfMocks(test));
} catch (IllegalAccessException e) {
throw new RuntimeException("Failed to get instance of object", e);
}
}
private List<Object> getListOfMocks(Object test) throws IllegalAccessException {
final Field[] declaredFields = test.getClass().getDeclaredFields();
List<Object> objects = new ArrayList<Object>();
for (Field field : declaredFields) {
if (field.getAnnotation(Mock.class) != null) {
field.setAccessible(true);
objects.add(field.get(test));
}
}
return objects;
}
private void setupRoboguice(Object test, List<Object> objects) {
RoboGuice.setBaseApplicationInjector(Robolectric.application, RoboGuice.DEFAULT_STAGE,
Modules.override(RoboGuice.newDefaultRoboModule(Robolectric.application))
.with(new MyRoboModule(objects)));
RoboGuice.injectMembers(Robolectric.application, test);
}
public static class MyRoboModule extends AbstractModule {
private List<Object> mocksToInject;
public MyRoboModule(List<Object> mocksToInject) {
this.mocksToInject = mocksToInject;
}
@Override
protected void configure() {
for (final Object mock : mocksToInject) {
Class clazz = mock.getClass();
bind(clazz.getSuperclass()).toInstance(mock);
}
}
}
}
Example usage:
Registrar.java
public class Registrar {
@Inject
private HttpConnection httpConnection;
public void register(User user) {
// stuff
}
}
HttpConnection.java
public class HttpConnection {
public Result execute(Request httpRequest) {
// stuff
return null;
}
}
And finally, our test class:
RegistrarTest.java
@RunWith(MocksInjectingTestRunner.class)
public class RegistrarTest {
@Mock
private HttpConnection httpConnection;
@Inject
private Registrar registrar;
@Test
public void mockShouldBeNotNull() {
assertNotNull(httpConnection);
}
@Test
public void shouldInjectMock() {
assertEquals(httpConnection, registrar.getHttpConnection());
}
}
Enjoy!
Written by Mateusz Herych
Related protips
Have a fresh tip? Share with Coderwall community!
Post
Post a tip
Best
#Java
Authors
Sponsored by #native_company# — Learn More
#native_title#
#native_desc#