kubek2k avatar kubek2k committed e38b2fc

Support for @Mock annotation arguments passing

Comments (0)

Files changed (8)

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/DesiredMockitoBeansFinder.java

 package org.kubek2k.springockito.annotations;
 
+import sun.reflect.annotation.AnnotationType;
+
 import java.lang.annotation.Annotation;
 import java.lang.reflect.Field;
 import java.util.HashMap;
 import java.util.Set;
 
 class DesiredMockitoBeansFinder {
-    public Map<String, Class<?>> findMockedBeans(Class<?> clazz) {
+    public static class MockProperties<AnnotationType extends Annotation> {
+        private AnnotationType annotationValues;
+
+        private Class<?> mockClass;
+
+        public MockProperties(AnnotationType annotationValues, Class<?> mockClass) {
+            this.annotationValues = annotationValues;
+            this.mockClass = mockClass;
+        }
+
+        public AnnotationType getAnnotationValues() {
+            return annotationValues;
+        }
+
+        public Class<?> getMockClass() {
+            return mockClass;
+        }
+    }
+
+    public Map<String, MockProperties<ReplaceWithMock>> findMockedBeans(Class<?> clazz) {
         return findAnnotatedFieldsTypes(clazz.getDeclaredFields(), ReplaceWithMock.class);
     }
 
         return findAnnotatedFieldsTypes(clazz.getDeclaredFields(), WrapWithSpy.class).keySet();
     }
 
-    private Map<String, Class<?>> findAnnotatedFieldsTypes(Field[] fieldsToScan, Class<? extends Annotation> annotationClass) {
-        Map<String, Class<?>> mockedBeans = new HashMap<String, Class<?>>();
+    private <AnnotationType extends Annotation> Map<String, MockProperties<AnnotationType>> findAnnotatedFieldsTypes(Field[] fieldsToScan, Class<AnnotationType> annotationClass) {
+        Map<String, MockProperties<AnnotationType>> mockedBeans = new HashMap<String, MockProperties<AnnotationType>>();
         for (Field field : fieldsToScan) {
-            if (field.getAnnotation(annotationClass) != null) {
-                mockedBeans.put(field.getName(), field.getType());
+            Annotation replaceWithMockAnnotation = field.getAnnotation(annotationClass);
+            if (replaceWithMockAnnotation != null) {
+                mockedBeans.put(field.getName(), new MockProperties<AnnotationType>((AnnotationType)field.getAnnotation(annotationClass), field.getType()));
             }
         }
         return mockedBeans;

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/MockitoBeansDefiner.java

 package org.kubek2k.springockito.annotations;
 
 import org.kubek2k.springockito.annotations.factory.MockFactoryBean;
+import org.mockito.Answers;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 
 class MockitoBeansDefiner {
-    public AbstractBeanDefinition createMockFactoryBeanDefinition(Class<?> mockClass) {
+    public AbstractBeanDefinition createMockFactoryBeanDefinition(Class<?> mockClass, Class[] extraInterfaces, String mockName, Answers defaultAnswer) {
         return BeanDefinitionBuilder.genericBeanDefinition(MockFactoryBean.class.getCanonicalName())
                 .addConstructorArgValue(mockClass)
+                .addConstructorArgValue(extraInterfaces)
+                .addConstructorArgValue(mockName)
+                .addConstructorArgValue(defaultAnswer)
                 .getBeanDefinition();
     }
 }

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/ReplaceWithMock.java

 package org.kubek2k.springockito.annotations;
 
+import org.mockito.Answers;
+
 import java.lang.annotation.ElementType;
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 @Retention(RetentionPolicy.RUNTIME)
 @Target(ElementType.FIELD)
 public @interface ReplaceWithMock {
+    String name() default "";
+
+    Answers defaultAnswer() default Answers.RETURNS_DEFAULTS;
+
+    Class[] extraInterfaces() default {};
 }

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/SpringockitoContextLoader.java

 
 public class SpringockitoContextLoader extends GenericXmlContextLoader {
 
-    private Map<String, Class<?>> mockedBeans = new HashMap<String, Class<?>>();
+    private Map<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>> mockedBeans
+            = new HashMap<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>>();
     private Set<String> spiedBeans;
 
     private DesiredMockitoBeansFinder mockedBeansFinder = new DesiredMockitoBeansFinder();
         registerSpies(context, spiedBeans);
     }
 
-    private void registerMocks(GenericApplicationContext context, Map<String, Class<?>> mockedBeans) {
-        for (Map.Entry<String, Class<?>> beanEntry : this.mockedBeans.entrySet()) {
+    private void registerMocks(GenericApplicationContext context,
+                               Map<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>> mockedBeans) {
+        for (Map.Entry<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>> beanEntry : this.mockedBeans.entrySet()) {
+            DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock> mockProperties = beanEntry.getValue();
+            ReplaceWithMock replaceWithMockAnnotation = mockProperties.getAnnotationValues();
             context.registerBeanDefinition(beanEntry.getKey(),
-                    mockitoBeansDefiner.createMockFactoryBeanDefinition(beanEntry.getValue()));
+                    mockitoBeansDefiner.createMockFactoryBeanDefinition(mockProperties.getMockClass(),
+                            replaceWithMockAnnotation.extraInterfaces(),
+                            replaceWithMockAnnotation.name(),
+                            replaceWithMockAnnotation.defaultAnswer()
+                    ));
         }
     }
 
 
         return super.modifyLocations(clazz, locations);
     }
-
-    void setMockedBeansFinder(DesiredMockitoBeansFinder mockedBeansFinder) {
-        this.mockedBeansFinder = mockedBeansFinder;
-    }
-
-    void setMockitoBeansDefiner(MockitoBeansDefiner mockitoBeansDefiner) {
-        this.mockitoBeansDefiner = mockitoBeansDefiner;
-    }
-    
-    void setMockitoSpiesDefiner(MockitoSpiesDefiner mockitoSpiesDefiner) {
-        this.mockitoSpiesDefiner = mockitoSpiesDefiner;
-    }
 }

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/factory/MockFactoryBean.java

 package org.kubek2k.springockito.annotations.factory;
 
+import org.mockito.Answers;
+import org.mockito.MockSettings;
 import org.mockito.Mockito;
+import org.mockito.internal.creation.MockSettingsImpl;
 import org.springframework.beans.factory.FactoryBean;
 
 
 public class MockFactoryBean<T> implements FactoryBean<T> {
 
     private Class<T> mockClass;
+    private final Class[] extraInterfaces;
+    private final String mockName;
+    private final Answers defaultAnswer;
     private T instance;
 
-    public MockFactoryBean(Class<T> mockClass) {
+    public MockFactoryBean(Class<T> mockClass, Class[] extraInterfaces, String mockName, Answers defaultAnswer) {
         this.mockClass = mockClass;
+        this.extraInterfaces = extraInterfaces;
+        this.mockName = mockName;
+        this.defaultAnswer = defaultAnswer;
     }
 
     public Class<? extends T> getObjectType() {
 
     public T getObject() throws Exception {
         if (instance == null) {
-            instance = Mockito.mock(mockClass);
+            instance = createInstance();
         }
         return instance;
     }
 
-    protected T createInstance(Class<T> mockClass) {
-        return Mockito.mock(mockClass);
+    private T createInstance() {
+        MockSettings mockSettings = new MockSettingsImpl().extraInterfaces(extraInterfaces);
+
+        if (defaultAnswer != null) {
+            mockSettings = mockSettings.defaultAnswer(defaultAnswer.get());
+        }
+
+        if (mockName != null) {
+            mockSettings = mockSettings.name(mockName);
+        }
+
+        return Mockito.mock(mockClass, mockSettings);
     }
 
 }

springockito-annotations/src/test/java/org/kubek2k/springockito/annotations/InnerBean.java

         return VALUE_RETURNED_BY_INNER;
     }
 
+    public Runnable methodReturningInteger() {
+        return null;
+    }
+
 }

springockito-annotations/src/test/java/org/kubek2k/springockito/annotations/SpringockitoAnnotationsComponentScanMocksIntegrationTest.java

 
 import static org.mockito.Mockito.verify;
 
+import junit.framework.Assert;
+import org.mockito.Answers;
+import org.mockito.internal.invocation.realmethod.CGLIBProxyRealMethod;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.annotation.DirtiesContext;
 import org.springframework.test.context.ContextConfiguration;
 @ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:/componentScanMockContext.xml")
 public class SpringockitoAnnotationsComponentScanMocksIntegrationTest extends AbstractTestNGSpringContextTests {
 
-    @ReplaceWithMock
+    @ReplaceWithMock(extraInterfaces = {Runnable.class}, defaultAnswer = Answers.RETURNS_MOCKS)
     @Autowired
     private InnerBean innerBean;
 
 
         verify(innerBean).doSomething();
     }
+
+    @Test
+    @DirtiesContext
+    public void shouldGiveBeanAnAdditionalInterface() {
+        Assert.assertTrue(innerBean instanceof Runnable);
+    }
+
+    @Test
+    @DirtiesContext
+    public void shouldConfigureBeanWithMockDefaultAnswer() {
+        // shouldn't fail - there's a mock returned
+        innerBean.methodReturningInteger().run();
+    }
+
+
 }

springockito-annotations/src/test/java/org/kubek2k/springockito/annotations/SpringockitoAnnotationsMocksIntegrationTest.java

 locations = "classpath:/mockContext.xml")
 public class SpringockitoAnnotationsMocksIntegrationTest extends AbstractTestNGSpringContextTests {
     
-    @ReplaceWithMock
+    @ReplaceWithMock()
     @Autowired
     private InnerBean innerBean;
     
     @Autowired
     private OuterBean outerBean;
-    
+
     @Test
     @DirtiesContext
     public void shouldUseMockInsteadOfOriginalBean() {
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.