package com.github.sbugat; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import org.junit.After; import org.mockito.Mock; import org.mockito.Mockito; /** * Generic test class to automatic check of all Mock marked with @Mock annotation by using verifyNoMoreInteractions on them. * * @author Sylvain Bugat * */ public abstract class GenericMockitoTest { /** * Scan all instance field to get all ones with @Mock annotation and call verifyNoMoreInteractions on them. * * @throws IllegalArgumentException reflexion exception when acceding fields * @throws IllegalAccessException reflexion exception when acceding fields */ @After public final void verifyNoMoreInteractionsAllMocks() throws IllegalArgumentException, IllegalAccessException { // Get all class from the test class to GenericMockitoTest class Class<? extends GenericMockitoTest> currentClass = this.getClass(); while (null != currentClass) { // Scan all fields of the current class for (final Field field : currentClass.getDeclaredFields()) { // Check if the current field has the @Mock annotation final Annotation annotation = field.getAnnotation(Mock.class); if (null != annotation) { // Get the mock object to check no more or no interactions final Object mockObject; if (field.isAccessible()) { mockObject = field.get(this); } // In the case of a unaccessible field (private, protected or package), set it accessible temporary else { field.setAccessible(true); mockObject = field.get(this); field.setAccessible(false); } Mockito.verifyNoMoreInteractions(mockObject); } } // Get the super class of the current class // An unchecked cast is needed because it's not possible to check generic type at runtime @SuppressWarnings("unchecked") final Class<? extends GenericMockitoTest> uncheckedCurrentClass = (Class<? extends GenericMockitoTest>) currentClass.getSuperclass(); currentClass = uncheckedCurrentClass; } } }