private Set<Object> instanceMocksIn(Object instance, Class<?> clazz) { Set<Object> instanceMocks = new HashSet<Object>(); Field[] declaredFields = clazz.getDeclaredFields(); for (Field declaredField : declaredFields) { if (declaredField.isAnnotationPresent(Mock.class) || declaredField.isAnnotationPresent(Spy.class)) { declaredField.setAccessible(true); try { Object fieldValue = declaredField.get(instance); if (fieldValue != null) { instanceMocks.add(fieldValue); } } catch (IllegalAccessException e) { throw new MockitoException("Could not access field " + declaredField.getName()); } } } return instanceMocks; }
@Override protected void configure() { Set<Field> f = ReflectionUtils.getAllFields(instanceToReadMocksFrom.getClass()); for (Field field : f) { if (field.getAnnotation(Mock.class) != null || field.getAnnotation(Spy.class) != null) { try { field.setAccessible(true); bindReflectedInstance(field.get(instanceToReadMocksFrom), field.getType()); } catch (Exception e) { throw new IllegalArgumentException("Unable to bind mock field " + field.getName() + " from " + instanceToReadMocksFrom.getClass().getName(), e); } } } }
private void registerMockitoTestClassMocksAndSpies(ApplicationContextMock applicationContext) { new Mirror().on(myTestClass.getClass()).reflectAll().fields().matching(f -> f.isAnnotationPresent(Mock.class) || f.isAnnotationPresent(Spy.class)).forEach( f -> { try { applicationContext.putOrReplaceBean(f.get(myTestClass)); } catch (IllegalAccessException e) { getLogger().trace(e.getMessage(), e); } } ); }
private void resetMocks(Object instance) { Iterable<InstanceField> toReset = Fields.allDeclaredFieldsOf(instance) .filter(annotatedBy(Mock.class, InjectMocks.class, Spy.class)) .notNull() .instanceFields(); for (InstanceField field : toReset) { field.set(null); } }
@SuppressWarnings({"deprecation", "unchecked"}) private Collection<Object> instanceMocksOf(Object instance) { return Fields.allDeclaredFieldsOf(instance) .filter(annotatedBy(Mock.class, Spy.class, MockitoAnnotations.Mock.class)) .notNull() .assignedValues(); }
@Test public void shouldFailIfTypeIsAnInterface() throws Exception { class FailingSpy { @Spy private List spyTypeIsInterface; } try { MockitoAnnotations.initMocks(new FailingSpy()); fail(); } catch (Exception e) { Assertions.assertThat(e.getMessage()).contains("an interface"); } }
@Test public void shouldReportWhenNoArgConstructor() throws Exception { class FailingSpy { @Spy NoValidConstructor noValidConstructor; } try { MockitoAnnotations.initMocks(new FailingSpy()); fail(); } catch (Exception e) { Assertions.assertThat(e.getMessage()).contains("default constructor"); } }
@Test public void shouldReportWhenConstructorThrows() throws Exception { class FailingSpy { @Spy ThrowingConstructor throwingConstructor; } try { MockitoAnnotations.initMocks(new FailingSpy()); fail(); } catch (Exception e) { Assertions.assertThat(e.getMessage()).contains("raised an exception"); } }
@Test public void shouldFailIfTypeIsAbstract() throws Exception { class FailingSpy { @Spy private AbstractList spyTypeIsAbstract; } try { MockitoAnnotations.initMocks(new FailingSpy()); fail(); } catch (Exception e) { Assertions.assertThat(e.getMessage()).contains("abstract class"); } }
@Test public void shouldFailIfTypeIsInnerClass() throws Exception { class FailingSpy { @Spy private TheInnerClass spyTypeIsInner; class TheInnerClass { } } try { MockitoAnnotations.initMocks(new FailingSpy()); fail(); } catch (MockitoException e) { Assertions.assertThat(e.getMessage()).contains("inner class"); } }
@Override protected boolean processInjection(Field field, Object fieldOwner, Set<Object> mockCandidates) { FieldReader fieldReader = new FieldReader(fieldOwner, field); // TODO refoctor : code duplicated in SpyAnnotationEngine if(!fieldReader.isNull() && field.isAnnotationPresent(Spy.class)) { try { Object instance = fieldReader.read(); if (new MockUtil().isMock(instance)) { // A. instance has been spied earlier // B. protect against multiple use of MockitoAnnotations.initMocks() Mockito.reset(instance); } else { new FieldSetter(fieldOwner, field).set( Mockito.mock(instance.getClass(), withSettings() .spiedInstance(instance) .defaultAnswer(Mockito.CALLS_REAL_METHODS) .name(field.getName())) ); } } catch (Exception e) { throw new MockitoException("Problems initiating spied field " + field.getName(), e); } } return false; }
@Override protected boolean isMockField(final Field field) { return hasAnnotation(Spy.class, Mock.class).test(field); }
public AnnotationResolver(TestClass testClass, Object target) { this(testClass, target, Inject.class, InjectMocks.class, Mock.class, Spy.class, InjectDelayed.class); }
@Test(expected=MockitoException.class) public void shouldNotAllowMockAndSpy() throws Exception { MockitoAnnotations.initMocks(new Object() { @Mock @Spy List mock; }); }
@Test(expected=MockitoException.class) public void shouldNotAllowSpyAndInjectMock() throws Exception { MockitoAnnotations.initMocks(new Object() { @InjectMocks @Spy List mock; }); }
@Test(expected=MockitoException.class) public void shouldNotAllowCaptorAndSpy() throws Exception { MockitoAnnotations.initMocks(new Object() { @Spy @Captor ArgumentCaptor captor; }); }
private boolean isAnnotatedByMockOrSpy(Field field) { return null != field.getAnnotation(Spy.class) || null != field.getAnnotation(Mock.class) || null != field.getAnnotation(MockitoAnnotations.Mock.class); }
public static void checkPreconditions(Object test) { checkThatFieldsAnnotatedWithAreNotNull(test, Bind.class); checkThatFieldsAnnotatedWithAreNotNull(test, Spy.class); checkThatFieldsAnnotatedWithMockAreNull(test); }
public void collectBindings(Object test) { collectBindings(test, Mock.class); collectBindings(test, Spy.class); collectBindings(test, Bind.class); }