Commits

pbatko committed b69c6e4

springockito
- change parent pom version
springockito-integration
- create it and start filling
springockito-annotations
- remove fake location generation
- add ability to reset mocks
- add various ways to define bean to be mocked
- repackage core
- set primary to true for bean spies
springockito-parent
- add fest-assert

Comments (0)

Files changed (97)

springockito-annotations/pom.xml

 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
 
     <groupId>org.kubek2k</groupId>
     <parent>
         <groupId>org.kubek2k</groupId>
         <artifactId>springockito-parent</artifactId>
-        <version>1.0.5</version>
+        <version>1.0.6-SNAPSHOT</version>
     </parent>
 
     <scm>
             <groupId>org.springframework</groupId>
             <artifactId>spring-context</artifactId>
         </dependency>
+
+        <!--test-->
         <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-test</artifactId>
         <dependency>
             <groupId>org.testng</groupId>
             <artifactId>testng</artifactId>
-            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.easytesting</groupId>
+            <artifactId>fest-assert</artifactId>
         </dependency>
     </dependencies>
 </project>

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

-package org.kubek2k.springockito.annotations;
-
-import java.lang.annotation.Annotation;
-import java.lang.reflect.Field;
-import java.util.*;
-
-class DesiredMockitoBeansFinder {
-    public static class MockProperties<AnnotationType extends Annotation> {
-        private AnnotationType annotationInstance;
-
-        private Class<?> mockClass;
-        private AnnotationClasspathRepresentationCreator<AnnotationType> annotationClasspathRepresentationCreator;
-
-        public MockProperties(AnnotationType annotationInstance, Class<?> mockClass, AnnotationClasspathRepresentationCreator<AnnotationType> annotationClasspathRepresentationCreator) {
-            this.annotationInstance = annotationInstance;
-            this.mockClass = mockClass;
-            this.annotationClasspathRepresentationCreator = annotationClasspathRepresentationCreator;
-        }
-
-        public AnnotationType getAnnotationInstance() {
-            return annotationInstance;
-        }
-
-        public Class<?> getMockClass() {
-            return mockClass;
-        }
-
-        public String getClasspathRepresentation() {
-            return mockClass + ":" + annotationClasspathRepresentationCreator.toClasspathRepresentation(annotationInstance);
-        }
-
-    }
-
-    private interface AnnotationClasspathRepresentationCreator<AnnotationType extends Annotation> {
-
-        public String toClasspathRepresentation(AnnotationType annotationType);
-
-    }
-
-    public Map<String, MockProperties<ReplaceWithMock>> findMockedBeans(Class<?> clazz) {
-        return findAnnotatedFieldsTypes(clazz.getDeclaredFields(), ReplaceWithMock.class, new AnnotationClasspathRepresentationCreator<ReplaceWithMock>() {
-            public String toClasspathRepresentation(ReplaceWithMock replaceWithMock) {
-                String defaultAnswer = replaceWithMock.defaultAnswer() != null ? replaceWithMock.defaultAnswer().toString() : "";
-                String extraInterfaces = replaceWithMock.extraInterfaces() != null ? Arrays.toString(replaceWithMock.extraInterfaces()) : "";
-                return replaceWithMock.name() + "," + defaultAnswer + "," + extraInterfaces;
-            }
-        });
-    }
-
-    public Set<String> findSpiedBeans(Class<?> clazz) {
-        return findAnnotatedFieldsTypes(clazz.getDeclaredFields(), WrapWithSpy.class, new AnnotationClasspathRepresentationCreator<WrapWithSpy>() {
-            public String toClasspathRepresentation(WrapWithSpy wrapWithSpy) {
-                return "";
-            }
-        }).keySet();
-    }
-
-    private <AnnotationType extends Annotation> Map<String, MockProperties<AnnotationType>> findAnnotatedFieldsTypes(Field[] fieldsToScan, Class<AnnotationType> annotationClass, AnnotationClasspathRepresentationCreator<AnnotationType> annotationClasspathRepresentationCreator) {
-        Map<String, MockProperties<AnnotationType>> mockedBeans = new LinkedHashMap<String, MockProperties<AnnotationType>>();
-        for (Field field : fieldsToScan) {
-            Annotation replaceWithMockAnnotation = field.getAnnotation(annotationClass);
-            if (replaceWithMockAnnotation != null) {
-                mockedBeans.put(field.getName(), new MockProperties<AnnotationType>((AnnotationType)field.getAnnotation(annotationClass), field.getType(), annotationClasspathRepresentationCreator));
-            }
-        }
-        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, Class[] extraInterfaces, String mockName, Answers defaultAnswer) {
-        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(MockFactoryBean.class.getCanonicalName())
-                .addConstructorArgValue(mockClass)
-                .addConstructorArgValue(extraInterfaces)
-                .addConstructorArgValue(mockName)
-                .addConstructorArgValue(defaultAnswer)
-                .getBeanDefinition();
-        beanDefinition.setPrimary(true);
-        return beanDefinition;
-    }
-}

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

-package org.kubek2k.springockito.annotations;
-
-import org.kubek2k.springockito.annotations.factory.SpyFactoryBean;
-import org.springframework.beans.factory.support.AbstractBeanDefinition;
-import org.springframework.beans.factory.support.BeanDefinitionBuilder;
-
-public class MockitoSpiesDefiner {
-
-    AbstractBeanDefinition createSpyDefinition(String wrappedBeanName) {
-        return BeanDefinitionBuilder
-                .rootBeanDefinition(SpyFactoryBean.class.getCanonicalName())
-                .addConstructorArgReference(wrappedBeanName)
-                .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;
-import java.lang.annotation.Target;
-
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-public @interface ReplaceWithMock {
-    String name() default "";
-
-    Answers defaultAnswer() default Answers.RETURNS_DEFAULTS;
-
-    Class[] extraInterfaces() default {};
-}
+package org.kubek2k.springockito.annotations;
+
+import org.mockito.Answers;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface ReplaceWithMock {
+
+    String name() default "";
+
+    Answers defaultAnswer() default Answers.RETURNS_DEFAULTS;
+
+    Class[] extraInterfaces() default {};
+
+    BeanNameStrategy beanNameStrategy() default BeanNameStrategy.DEFAULT;
+
+    String beanName() default "";
+
+    public enum BeanNameStrategy {
+        DEFAULT,
+        FIELD_NAME,
+        FIELD_TYPE_NAME
+    }
+
+}

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

-package org.kubek2k.springockito.annotations;
-
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.context.support.GenericApplicationContext;
-import org.springframework.test.context.support.GenericXmlContextLoader;
-
-import java.util.*;
-
-public class SpringockitoContextLoader extends GenericXmlContextLoader {
-
-    /**
-     * Have to be sorted since we want a nice caching of customized application contexts
-     */
-    private Map<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>> mockedBeans
-            = new TreeMap<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>>();
-    private Set<String> spiedBeans = new TreeSet<String>();
-
-    private DesiredMockitoBeansFinder mockedBeansFinder = new DesiredMockitoBeansFinder();
-
-    private MockitoBeansDefiner mockitoBeansDefiner = new MockitoBeansDefiner();
-    private MockitoSpiesDefiner mockitoSpiesDefiner = new MockitoSpiesDefiner();
-
-    @Override
-    protected void customizeContext(GenericApplicationContext context) {
-        super.customizeContext(context);
-        registerMocks(context, mockedBeans);
-        registerSpies(context, spiedBeans);
-    }
-
-    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.getAnnotationInstance();
-            context.registerBeanDefinition(beanEntry.getKey(),
-                    mockitoBeansDefiner.createMockFactoryBeanDefinition(mockProperties.getMockClass(),
-                            replaceWithMockAnnotation.extraInterfaces(),
-                            replaceWithMockAnnotation.name(),
-                            replaceWithMockAnnotation.defaultAnswer()
-                    ));
-        }
-    }
-
-    private void registerSpies(GenericApplicationContext context, Set<String> spiedBeanNames) {
-        for (String beanName : spiedBeanNames) {
-            BeanDefinition beanDefinition = context.getBeanDefinition(beanName);
-            String wrappedBeanName = beanName + "$$WRAPPED_WITH_SPY";
-            context.registerBeanDefinition(wrappedBeanName, beanDefinition);
-            context.registerBeanDefinition(beanName, mockitoSpiesDefiner.createSpyDefinition(wrappedBeanName));
-        }
-    }
-
-    private void defineMocksAndSpies(Class<?> clazz) {
-        this.mockedBeans.putAll(mockedBeansFinder.findMockedBeans(clazz));
-        this.spiedBeans.addAll(mockedBeansFinder.findSpiedBeans(clazz));
-    }
-
-    private List<String> generateLocationForMocksAndSpies() {
-        List<String> result = new ArrayList<String>(mockedBeans.size() + spiedBeans.size());
-
-        for (Map.Entry<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>> mockDefinitionEntry : mockedBeans.entrySet()) {
-            result.add("classpath*:/mock-" + mockDefinitionEntry.getKey() + "=" + mockDefinitionEntry.getValue().getClasspathRepresentation());
-        }
-
-        for (String spiedBean : spiedBeans) {
-            result.add("classpath*:/spy-" + spiedBean);
-        }
-
-        return result;
-    }
-
-    // I know I could use commons or sth but I don't want to introduce more deps than are actually really really needed
-    private <T> List<T> merge(List<T> list1, List<T> list2) {
-        List<T> result = new ArrayList<T>(list1.size() + list2.size());
-
-        result.addAll(list1);
-        result.addAll(list2);
-
-        return result;
-    }
-
-    private String[] addFakeLocationsOfBeansAndSpies(String[] locations) {
-        List<String> locationOfMocksAndSpies = generateLocationForMocksAndSpies();
-        return merge(Arrays.asList(locations), locationOfMocksAndSpies)
-                .toArray(new String[locations.length + locationOfMocksAndSpies.size()]);
-    }
-
-    @Override
-    protected String[] generateDefaultLocations(Class<?> clazz) {
-        String[] resultingLocations = super.generateDefaultLocations(clazz);
-
-        defineMocksAndSpies(clazz);
-
-        return addFakeLocationsOfBeansAndSpies(resultingLocations);
-
-    }
-
-    @Override
-    protected String[] modifyLocations(Class<?> clazz, String... passedLocations) {
-        String[] resultingLocations = super.modifyLocations(clazz, passedLocations);
-
-        defineMocksAndSpies(clazz);
-
-        return addFakeLocationsOfBeansAndSpies(resultingLocations);
-    }
-}
+package org.kubek2k.springockito.annotations;
+
+import org.kubek2k.springockito.annotations.internal.DesiredMockitoBeansFinder;
+import org.kubek2k.springockito.annotations.internal.MockitoBeansDefiner;
+import org.kubek2k.springockito.annotations.internal.MockitoSpiesDefiner;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.context.support.GenericApplicationContext;
+import org.springframework.test.context.support.GenericXmlContextLoader;
+
+import java.util.*;
+
+public class SpringockitoContextLoader extends GenericXmlContextLoader {
+
+    /**
+     * Have to be sorted since we want a nice caching of customized application contexts
+     */
+    private Map<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>> mockedBeans
+            = new TreeMap<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>>();
+    private Set<String> spiedBeans = new TreeSet<String>();
+
+    private DesiredMockitoBeansFinder mockedBeansFinder = new DesiredMockitoBeansFinder();
+
+    private MockitoBeansDefiner mockitoBeansDefiner = new MockitoBeansDefiner();
+    private MockitoSpiesDefiner mockitoSpiesDefiner = new MockitoSpiesDefiner();
+
+    @Override
+    protected void customizeContext(GenericApplicationContext context) {
+        super.customizeContext(context);
+        registerMocks(context, mockedBeans);
+        registerSpies(context, spiedBeans);
+    }
+
+    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.getAnnotationInstance();
+            context.registerBeanDefinition(beanEntry.getKey(),
+                    mockitoBeansDefiner.createMockFactoryBeanDefinition(mockProperties.getMockClass(),
+                            replaceWithMockAnnotation.extraInterfaces(),
+                            replaceWithMockAnnotation.name(),
+                            replaceWithMockAnnotation.defaultAnswer()
+                    ));
+        }
+    }
+
+    private void registerSpies(GenericApplicationContext context, Set<String> spiedBeanNames) {
+        for (String beanName : spiedBeanNames) {
+            BeanDefinition beanDefinition = context.getBeanDefinition(beanName);
+            String wrappedBeanName = beanName + "$$WRAPPED_WITH_SPY";
+            context.registerBeanDefinition(wrappedBeanName, beanDefinition);
+            context.registerBeanDefinition(beanName, mockitoSpiesDefiner.createSpyDefinition(wrappedBeanName));
+        }
+    }
+
+    private void defineMocksAndSpies(Class<?> clazz) {
+        this.mockedBeans.putAll(mockedBeansFinder.findMockedBeans(clazz));
+        this.spiedBeans.addAll(mockedBeansFinder.findSpiedBeans(clazz));
+    }
+
+    private List<String> generateLocationForMocksAndSpies() {
+        List<String> result = new ArrayList<String>(mockedBeans.size() + spiedBeans.size());
+
+        for (Map.Entry<String, DesiredMockitoBeansFinder.MockProperties<ReplaceWithMock>> mockDefinitionEntry : mockedBeans.entrySet()) {
+            result.add("classpath*:/mock-" + mockDefinitionEntry.getKey() + "=" + mockDefinitionEntry.getValue().getClasspathRepresentation());
+        }
+
+        for (String spiedBean : spiedBeans) {
+            result.add("classpath*:/spy-" + spiedBean);
+        }
+
+        return result;
+    }
+
+    // I know I could use commons or sth but I don't want to introduce more deps than are actually really really needed
+    private <T> List<T> merge(List<T> list1, List<T> list2) {
+        List<T> result = new ArrayList<T>(list1.size() + list2.size());
+
+        result.addAll(list1);
+        result.addAll(list2);
+
+        return result;
+    }
+
+    @Override
+    protected String[] generateDefaultLocations(Class<?> clazz) {
+        String[] resultingLocations = super.generateDefaultLocations(clazz);
+
+        defineMocksAndSpies(clazz);
+
+        return resultingLocations;
+
+    }
+
+    @Override
+    protected String[] modifyLocations(Class<?> clazz, String... passedLocations) {
+        String[] resultingLocations = super.modifyLocations(clazz, passedLocations);
+
+        defineMocksAndSpies(clazz);
+
+        return resultingLocations;
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/experimental/DirtiesMocks.java

+package org.kubek2k.springockito.annotations.experimental;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface DirtiesMocks {
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/experimental/DirtiesMocksTestContextListener.java

+package org.kubek2k.springockito.annotations.experimental;
+
+import org.kubek2k.springockito.annotations.internal.ResettableMock;
+import org.springframework.context.ApplicationContext;
+import org.springframework.test.context.TestContext;
+import org.springframework.test.context.support.AbstractTestExecutionListener;
+
+import java.lang.reflect.Method;
+import java.util.Map;
+
+public class DirtiesMocksTestContextListener extends AbstractTestExecutionListener {
+    @Override
+    public void afterTestMethod(TestContext testContext) throws Exception {
+        Method testMethod = testContext.getTestMethod();
+        if (testMethod.isAnnotationPresent(DirtiesMocks.class)) {
+            ApplicationContext applicationContext = testContext.getApplicationContext();
+            Map<String, ResettableMock> beansOfType = applicationContext.getBeansOfType(ResettableMock.class);
+            for (ResettableMock resettableMock : beansOfType.values()) {
+                resettableMock.resetMock();
+            }
+        }
+    }
+}

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, Class[] extraInterfaces, String mockName, Answers defaultAnswer) {
-        this.mockClass = mockClass;
-        this.extraInterfaces = extraInterfaces;
-        this.mockName = mockName;
-        this.defaultAnswer = defaultAnswer;
-    }
-
-    public Class<? extends T> getObjectType() {
-        return mockClass;
-    }
-
-    public boolean isSingleton() {
-        return true;
-    }
-
-    public T getObject() throws Exception {
-        if (instance == null) {
-            instance = createInstance();
-        }
-        return instance;
-    }
-
-    private T createInstance() {
-        MockSettings mockSettings = new MockSettingsImpl();
-
-        if (extraInterfaces.length > 0) {
-            mockSettings = mockSettings.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/main/java/org/kubek2k/springockito/annotations/factory/SpyFactoryBean.java

-package org.kubek2k.springockito.annotations.factory;
-
-import org.mockito.Mockito;
-import org.springframework.beans.factory.FactoryBean;
-
-public class SpyFactoryBean<T> implements FactoryBean<T> {
-
-    private T wrappedInstance;
-
-    private T spyInstance;
-    
-    public SpyFactoryBean(T wrappedInstance) {
-        this.wrappedInstance = wrappedInstance;
-    }
-    
-    public T getObject() throws Exception {
-        if (spyInstance == null) {
-            spyInstance = Mockito.spy(wrappedInstance);
-        }
-        
-        return spyInstance;
-    }
-
-    @SuppressWarnings("unchecked")
-    public Class<? extends T> getObjectType() {
-        return (Class<? extends T>) wrappedInstance.getClass();
-    }
-
-    public boolean isSingleton() {
-        return true;
-    }
-}

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

+package org.kubek2k.springockito.annotations.internal;
+
+import org.kubek2k.springockito.annotations.ReplaceWithMock;
+import org.kubek2k.springockito.annotations.WrapWithSpy;
+import org.kubek2k.springockito.annotations.internal.naming.BeanNameResolver;
+import org.kubek2k.springockito.annotations.internal.naming.BeanNameResolverChainOfResponsibility;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class DesiredMockitoBeansFinder {
+
+    private final BeanNameResolver beanNameResolver = new BeanNameResolverChainOfResponsibility();
+
+    public static class MockProperties<AnnotationType extends Annotation> {
+        private AnnotationType annotationInstance;
+
+        private Class<?> mockClass;
+        private AnnotationClasspathRepresentationCreator<AnnotationType> annotationClasspathRepresentationCreator;
+
+        public MockProperties(AnnotationType annotationInstance, Class<?> mockClass, AnnotationClasspathRepresentationCreator<AnnotationType> annotationClasspathRepresentationCreator) {
+            this.annotationInstance = annotationInstance;
+            this.mockClass = mockClass;
+            this.annotationClasspathRepresentationCreator = annotationClasspathRepresentationCreator;
+        }
+
+        public AnnotationType getAnnotationInstance() {
+            return annotationInstance;
+        }
+
+        public Class<?> getMockClass() {
+            return mockClass;
+        }
+
+        public String getClasspathRepresentation() {
+            return mockClass + ":" + annotationClasspathRepresentationCreator.toClasspathRepresentation(annotationInstance);
+        }
+
+    }
+
+    private interface AnnotationClasspathRepresentationCreator<AnnotationType extends Annotation> {
+
+        public String toClasspathRepresentation(AnnotationType annotationType);
+
+    }
+
+    public Map<String, MockProperties<ReplaceWithMock>> findMockedBeans(Class<?> clazz) {
+        return findAnnotatedWithReplaceByMockFieldsTypes(clazz.getDeclaredFields(), ReplaceWithMock.class, new AnnotationClasspathRepresentationCreator<ReplaceWithMock>() {
+            public String toClasspathRepresentation(ReplaceWithMock replaceWithMock) {
+                String defaultAnswer = replaceWithMock.defaultAnswer() != null ? replaceWithMock.defaultAnswer().toString() : "";
+                String extraInterfaces = replaceWithMock.extraInterfaces() != null ? Arrays.toString(replaceWithMock.extraInterfaces()) : "";
+                return replaceWithMock.name() + "," + defaultAnswer + "," + extraInterfaces;
+            }
+        });
+    }
+
+    public Set<String> findSpiedBeans(Class<?> clazz) {
+        return findAnnotatedWithWrapWithSpyFieldsTypes(clazz.getDeclaredFields(), WrapWithSpy.class, new AnnotationClasspathRepresentationCreator<WrapWithSpy>() {
+            public String toClasspathRepresentation(WrapWithSpy wrapWithSpy) {
+                return "";
+            }
+        }).keySet();
+    }
+
+    private <AnnotationType extends Annotation> Map<String, MockProperties<AnnotationType>> findAnnotatedWithReplaceByMockFieldsTypes(Field[] fieldsToScan, Class<AnnotationType> annotationClass, AnnotationClasspathRepresentationCreator<AnnotationType> annotationClasspathRepresentationCreator) {
+        Map<String, MockProperties<AnnotationType>> mockedBeans = new LinkedHashMap<String, MockProperties<AnnotationType>>();
+        for (Field field : fieldsToScan) {
+            Annotation replaceWithMockAnnotation = field.getAnnotation(annotationClass);
+            if (replaceWithMockAnnotation != null) {
+                String beanName = getBeanName(field);
+                mockedBeans.put(beanName, new MockProperties<AnnotationType>((AnnotationType) field.getAnnotation(annotationClass), field.getType(), annotationClasspathRepresentationCreator));
+            }
+        }
+        return mockedBeans;
+    }
+
+    private <AnnotationType extends Annotation> Map<String, MockProperties<AnnotationType>> findAnnotatedWithWrapWithSpyFieldsTypes(Field[] fieldsToScan, Class<AnnotationType> annotationClass, AnnotationClasspathRepresentationCreator<AnnotationType> annotationClasspathRepresentationCreator) {
+        Map<String, MockProperties<AnnotationType>> mockedBeans = new LinkedHashMap<String, MockProperties<AnnotationType>>();
+        for (Field field : fieldsToScan) {
+            Annotation replaceWithMockAnnotation = field.getAnnotation(annotationClass);
+            if (replaceWithMockAnnotation != null) {
+                String beanName = field.getName();
+                mockedBeans.put(beanName, new MockProperties<AnnotationType>((AnnotationType) field.getAnnotation(annotationClass), field.getType(), annotationClasspathRepresentationCreator));
+            }
+        }
+        return mockedBeans;
+    }
+
+    private String getBeanName(Field field) {
+        return beanNameResolver.retrieveBeanName(field);
+    }
+}

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

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

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/MockitoSpiesDefiner.java

+package org.kubek2k.springockito.annotations.internal;
+
+import org.kubek2k.springockito.annotations.internal.factory.SpyFactoryBean;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+
+public class MockitoSpiesDefiner {
+
+    public AbstractBeanDefinition createSpyDefinition(String wrappedBeanName) {
+        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder
+                .rootBeanDefinition(SpyFactoryBean.class.getCanonicalName())
+                .addConstructorArgReference(wrappedBeanName)
+                .getBeanDefinition();
+        beanDefinition.setPrimary(true);
+        return beanDefinition;
+    }
+
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/ResettableMock.java

+package org.kubek2k.springockito.annotations.internal;
+
+public interface ResettableMock {
+    void resetMock();
+}

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

+package org.kubek2k.springockito.annotations.internal.factory;
+
+import org.kubek2k.springockito.annotations.internal.ResettableMock;
+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>, ResettableMock {
+
+    private Class<T> mockClass;
+    private final Class[] extraInterfaces;
+    private final String mockName;
+    private final Answers defaultAnswer;
+    private T instance;
+
+    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() {
+        return mockClass;
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public T getObject() throws Exception {
+        if (instance == null) {
+            instance = createInstance();
+        }
+        return instance;
+    }
+
+    private T createInstance() {
+        MockSettings mockSettings = new MockSettingsImpl();
+
+        if (extraInterfaces.length > 0) {
+            mockSettings = mockSettings.extraInterfaces(extraInterfaces);
+        }
+
+        if (defaultAnswer != null) {
+            mockSettings = mockSettings.defaultAnswer(defaultAnswer.get());
+        }
+
+        if (mockName != null) {
+            mockSettings = mockSettings.name(mockName);
+        }
+
+        return Mockito.mock(mockClass, mockSettings);
+    }
+
+    public void resetMock() {
+        T object = null;
+        try {
+            object = getObject();
+            Mockito.reset(object);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/factory/SpyFactoryBean.java

+package org.kubek2k.springockito.annotations.internal.factory;
+
+import org.mockito.Mockito;
+import org.springframework.beans.factory.FactoryBean;
+
+public class SpyFactoryBean<T> implements FactoryBean<T> {
+
+    private T wrappedInstance;
+
+    private T spyInstance;
+
+    public SpyFactoryBean(T wrappedInstance) {
+        this.wrappedInstance = wrappedInstance;
+    }
+
+    public T getObject() throws Exception {
+        if (spyInstance == null) {
+            spyInstance = Mockito.spy(wrappedInstance);
+        }
+
+        return spyInstance;
+    }
+
+    @SuppressWarnings("unchecked")
+    public Class<? extends T> getObjectType() {
+        return (Class<? extends T>) wrappedInstance.getClass();
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/BeanNameResolver.java

+package org.kubek2k.springockito.annotations.internal.naming;
+
+import java.lang.reflect.Field;
+
+public interface BeanNameResolver {
+
+    String retrieveBeanName(Field field);
+
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/BeanNameResolverChainOfResponsibility.java

+package org.kubek2k.springockito.annotations.internal.naming;
+
+import org.kubek2k.springockito.annotations.internal.naming.strategies.*;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public class BeanNameResolverChainOfResponsibility implements BeanNameResolver {
+
+    List<AbstractBeanNameResolver> resolversChain;
+    AbstractBeanNameResolver defaultResolver;
+
+    public BeanNameResolverChainOfResponsibility() {
+        this.defaultResolver = new ExplicitBeanNameStrategyBeanNameResolver();
+        this.resolversChain = new ArrayList<AbstractBeanNameResolver>();
+        Collections.addAll(resolversChain,
+                new ExplicitBeanNameNameResolver(),
+                new ExplicitBeanNameStrategyBeanNameResolver(),
+                new QualifierBeanNameResolver(),
+                new ResourceBeanNameResolver(),
+                new ImplicitBeanNameStrategyBeanNameResolver()
+        );
+    }
+
+    public String retrieveBeanName(Field field) {
+        for (AbstractBeanNameResolver resolver : resolversChain) {
+            if (resolver.canGetBeanName(field)) {
+                return resolver.retrieveBeanName(field);
+            }
+        }
+        return getFallbackDefault(field);
+    }
+
+    private String getFallbackDefault(Field field) {
+        return field.getName();
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/strategies/AbstractBeanNameResolver.java

+package org.kubek2k.springockito.annotations.internal.naming.strategies;
+
+import org.kubek2k.springockito.annotations.internal.naming.BeanNameResolver;
+
+import java.lang.reflect.Field;
+
+public abstract class AbstractBeanNameResolver implements BeanNameResolver {
+
+    protected abstract String resolveBeanName(Field field);
+
+    public String retrieveBeanName(Field field) {
+        return resolveBeanName(field);
+    }
+
+    public boolean canGetBeanName(Field field) {
+        String beanName = resolveBeanName(field);
+        return isBlank(beanName);
+    }
+
+    private boolean isBlank(String beanName) {
+        return beanName != null && !beanName.isEmpty();
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/strategies/ExplicitBeanNameNameResolver.java

+package org.kubek2k.springockito.annotations.internal.naming.strategies;
+
+import org.kubek2k.springockito.annotations.ReplaceWithMock;
+
+import java.lang.reflect.Field;
+
+public class ExplicitBeanNameNameResolver extends AbstractBeanNameResolver {
+
+    @Override
+    protected String resolveBeanName(Field field) {
+        return field.getAnnotation(ReplaceWithMock.class).beanName();
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/strategies/ExplicitBeanNameStrategyBeanNameResolver.java

+package org.kubek2k.springockito.annotations.internal.naming.strategies;
+
+import org.kubek2k.springockito.annotations.ReplaceWithMock;
+
+import java.lang.reflect.Field;
+
+import static org.kubek2k.springockito.annotations.ReplaceWithMock.BeanNameStrategy.FIELD_NAME;
+import static org.kubek2k.springockito.annotations.ReplaceWithMock.BeanNameStrategy.FIELD_TYPE_NAME;
+
+public class ExplicitBeanNameStrategyBeanNameResolver extends AbstractBeanNameResolver {
+
+    @Override
+    protected String resolveBeanName(Field field) {
+        ReplaceWithMock.BeanNameStrategy beanNameStrategy = field.getAnnotation(ReplaceWithMock.class).beanNameStrategy();
+        if (beanNameStrategy == FIELD_NAME) {
+            return field.getName();
+        } else if (beanNameStrategy == FIELD_TYPE_NAME) {
+            return field.getType().getName();
+        }
+        return null;
+    }
+
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/strategies/ImplicitBeanNameStrategyBeanNameResolver.java

+package org.kubek2k.springockito.annotations.internal.naming.strategies;
+
+import org.kubek2k.springockito.annotations.ReplaceWithMock;
+
+import java.lang.reflect.Field;
+
+import static org.kubek2k.springockito.annotations.ReplaceWithMock.BeanNameStrategy.DEFAULT;
+
+public class ImplicitBeanNameStrategyBeanNameResolver extends AbstractBeanNameResolver {
+    @Override
+    protected String resolveBeanName(Field field) {
+        ReplaceWithMock.BeanNameStrategy beanNameStrategy = field.getAnnotation(ReplaceWithMock.class).beanNameStrategy();
+        if (beanNameStrategy == DEFAULT) {
+            return field.getName();
+        }
+        return null;
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/strategies/QualifierBeanNameResolver.java

+package org.kubek2k.springockito.annotations.internal.naming.strategies;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import java.lang.reflect.Field;
+
+public class QualifierBeanNameResolver extends AbstractBeanNameResolver {
+
+    @Override
+    protected String resolveBeanName(Field field) {
+        Qualifier annotation = field.getAnnotation(Qualifier.class);
+        if (annotation == null) {
+            return null;
+        }
+        return annotation.value();
+    }
+}

springockito-annotations/src/main/java/org/kubek2k/springockito/annotations/internal/naming/strategies/ResourceBeanNameResolver.java

+package org.kubek2k.springockito.annotations.internal.naming.strategies;
+
+import javax.annotation.Resource;
+import java.lang.reflect.Field;
+
+public class ResourceBeanNameResolver extends AbstractBeanNameResolver {
+
+    @Override
+    protected String resolveBeanName(Field field) {
+        Resource resource = field.getAnnotation(Resource.class);
+        if (resource == null) {
+            return null;
+        }
+        return resource.name();
+    }
+
+}

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

-package org.kubek2k.springockito.annotations;
-
-public class InnerBean {
-
-    public static final int VALUE_RETURNED_BY_INNER = 300;
-
-    public int doSomething() {
-        return VALUE_RETURNED_BY_INNER;
-    }
-
-    public Runnable methodReturningInteger() {
-        return null;
-    }
-
-}

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

-package org.kubek2k.springockito.annotations;
-
-public class OuterBean {
-    private InnerBean innerBean;
-
-    public void setInnerBean(InnerBean innerBean) {
-        this.innerBean = innerBean;
-    }
-    
-    public int doSomething() {
-        return innerBean.doSomething();
-    }
-}

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

-package org.kubek2k.springockito.annotations;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-
-@Component
-public class OuterBeanWithAutowired {
-
-    @Autowired
-    private InnerBean innerBean;
-
-    public void setInnerBean(InnerBean innerBean) {
-        this.innerBean = innerBean;
-    }
-
-    public int doSomething() {
-        return innerBean.doSomething();
-    }
-}

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

-package org.kubek2k.springockito.annotations;
-
-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;
-import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
-import org.testng.annotations.Test;
-
-@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:/componentScanMockContext.xml")
-public class SpringockitoAnnotationsComponentScanMocksIntegrationTest extends AbstractTestNGSpringContextTests {
-
-    @ReplaceWithMock(extraInterfaces = {Runnable.class}, defaultAnswer = Answers.RETURNS_MOCKS)
-    @Autowired
-    private InnerBean innerBean;
-
-    @Autowired
-    private OuterBeanWithAutowired outerBean;
-
-    @Test
-    @DirtiesContext
-    public void shouldUseMockInsteadOfOriginalBean() {
-        outerBean.doSomething();
-
-        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/SpringockitoAnnotationsComponentScanSpiesIntegrationTest.java

-package org.kubek2k.springockito.annotations;
-
-import static org.mockito.Mockito.verify;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-@ContextConfiguration(loader = SpringockitoContextLoader.class,
-locations = "classpath:/componentScanMockContext.xml")
-public class SpringockitoAnnotationsComponentScanSpiesIntegrationTest extends AbstractTestNGSpringContextTests {
-    
-    @WrapWithSpy
-    @Autowired
-    private InnerBean innerBean;
-    
-    @Autowired
-    private OuterBeanWithAutowired outerBean;
-    
-    @Test
-    @DirtiesContext
-    public void shouldUseMockInsteadOfOriginalBean() {
-        int result = outerBean.doSomething();
-        
-        Assert.assertEquals(InnerBean.VALUE_RETURNED_BY_INNER, result);
-        verify(innerBean).doSomething();
-    }
-}

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

-package org.kubek2k.springockito.annotations;
-
-import static org.mockito.Mockito.verify;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
-import org.testng.annotations.Test;
-
-@ContextConfiguration(loader = SpringockitoContextLoader.class,
-locations = "classpath:/mockContext.xml")
-public class SpringockitoAnnotationsMocksIntegrationTest extends AbstractTestNGSpringContextTests {
-    
-    @ReplaceWithMock
-    @Autowired
-    private InnerBean innerBean;
-    
-    @Autowired
-    private OuterBean outerBean;
-
-    @Test
-    @DirtiesContext
-    public void shouldUseMockInsteadOfOriginalBean() {
-        outerBean.doSomething();
-        
-        verify(innerBean).doSomething();
-    }
-    
-}

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

-package org.kubek2k.springockito.annotations;
-
-import static org.mockito.Mockito.verify;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.test.annotation.DirtiesContext;
-import org.springframework.test.context.ContextConfiguration;
-import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
-import org.testng.Assert;
-import org.testng.annotations.Test;
-
-@ContextConfiguration(loader = SpringockitoContextLoader.class,
-locations = "classpath:/mockContext.xml")
-public class SpringockitoAnnotationsSpiesIntegrationTest extends AbstractTestNGSpringContextTests {
-
-    @WrapWithSpy
-    @Autowired
-    private InnerBean innerBean;
-    
-    @Autowired
-    private OuterBean outerBean;
-    
-    @Test
-    @DirtiesContext
-    public void shouldUseSpyInsteadOfOriginalBean() {
-        int result = outerBean.doSomething();
-        
-        // the actual returned value is real and we can verify interaction
-        Assert.assertEquals(result, InnerBean.VALUE_RETURNED_BY_INNER);
-        verify(innerBean).doSomething();
-    }
-    
-}

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

-package org.kubek2k.springockito.annotations;
-
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.verifyNoMoreInteractions;
-
-import org.springframework.context.ApplicationContext;
-import org.testng.annotations.Test;
-
-public class SpringockitoContextLoaderTest {
-    @Test
-    public void shouldLoadMockBean() throws Exception {
-        // given
-        SpringockitoContextLoader loader = new SpringockitoContextLoader();
-
-        // when
-        loader.processLocations(SomeTestClass.class);
-        ApplicationContext context = loader.loadContext("classpath:/mockContext.xml");
-
-        // then
-        OuterBean outerBean = (OuterBean) context.getBean("outerBean1");
-
-        // verification that it's a mock
-        verifyNoMoreInteractions(outerBean);
-
-    }
-    
-    @Test
-    public void shouldLoadSpyBean() throws Exception {
-        // given
-        SpringockitoContextLoader loader = new SpringockitoContextLoader();
-
-        // when
-        loader.processLocations(SomeTestClass.class);
-        ApplicationContext context = loader.loadContext("classpath:/mockContext.xml");
-
-        // then
-        OuterBean outer =  (OuterBean) context.getBean("outerBean");
-        outer.doSomething();
-        
-        // verification that it's a spy
-        verify(outer).doSomething();
-    }
-
-    public static class SomeTestClass {
-        @SuppressWarnings("unused")
-        @ReplaceWithMock
-        private OuterBean outerBean1;
-        
-        @SuppressWarnings("unused")
-        @WrapWithSpy
-        private OuterBean outerBean;
-    }
-
-
-    public static interface X {
-        public int hello();
-    }
-
-}
+package org.kubek2k.springockito.annotations;
+
+import org.kubek2k.springockito.annotations.it.beans.OuterBean;
+import org.springframework.context.ApplicationContext;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+public class SpringockitoContextLoaderTest {
+    @Test
+    public void shouldLoadMockBean() throws Exception {
+        // given
+        SpringockitoContextLoader loader = new SpringockitoContextLoader();
+
+        // when
+        loader.processLocations(SomeTestClass.class);
+        ApplicationContext context = loader.loadContext("classpath:/mockContext.xml");
+
+        // then
+        OuterBean outerBean = (OuterBean) context.getBean("outerBean1");
+
+        // verification that it's a mock
+        verifyNoMoreInteractions(outerBean);
+
+    }
+
+    @Test
+    public void shouldLoadSpyBean() throws Exception {
+        // given
+        SpringockitoContextLoader loader = new SpringockitoContextLoader();
+
+        // when
+        loader.processLocations(SomeTestClass.class);
+        ApplicationContext context = loader.loadContext("classpath:/mockContext.xml");
+
+        // then
+        OuterBean outer = (OuterBean) context.getBean("outerBean");
+        outer.doSomething();
+
+        // verification that it's a spy
+        verify(outer).doSomething();
+    }
+
+    public static class SomeTestClass {
+        @SuppressWarnings("unused")
+        @ReplaceWithMock
+        private OuterBean outerBean1;
+
+        @SuppressWarnings("unused")
+        @WrapWithSpy
+        private OuterBean outerBean;
+    }
+
+
+    public static interface X {
+        public int hello();
+    }
+
+}

springockito-annotations/src/test/java/org/kubek2k/springockito/annotations/contextcache/NoSpringockitoIntegrationTest.java

 package org.kubek2k.springockito.annotations.contextcache;
 
 import junit.framework.Assert;
-import org.kubek2k.springockito.annotations.InnerBean;
+import org.kubek2k.springockito.annotations.it.beans.InnerBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
 
     @Test
     public void shouldBeAnActualBean() {
-         Assert.assertEquals(InnerBean.class, innerBean.getClass());
+        Assert.assertEquals(InnerBean.class, innerBean.getClass());
     }
 }

springockito-annotations/src/test/java/org/kubek2k/springockito/annotations/contextcache/SpringockitoIntegrationTest.java

 package org.kubek2k.springockito.annotations.contextcache;
 
-import junit.framework.Assert;
-import org.kubek2k.springockito.annotations.InnerBean;
 import org.kubek2k.springockito.annotations.ReplaceWithMock;
 import org.kubek2k.springockito.annotations.SpringockitoContextLoader;
+import org.kubek2k.springockito.annotations.it.beans.InnerBean;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;

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

+package org.kubek2k.springockito.annotations.it;
+
+import junit.framework.Assert;
+import org.kubek2k.springockito.annotations.ReplaceWithMock;
+import org.kubek2k.springockito.annotations.SpringockitoContextLoader;
+import org.kubek2k.springockito.annotations.it.beans.InnerBean;
+import org.kubek2k.springockito.annotations.it.beans.OuterBeanWithAutowired;
+import org.mockito.Answers;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.test.annotation.DirtiesContext;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
+import org.testng.annotations.Test;
+
+import static org.mockito.Mockito.verify;
+
+@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:/componentScanMockContext.xml")
+public class SpringockitoAnnotationsComponentScanMocksIntegrationTest extends AbstractTestNGSpringContextTests {
+
+    @ReplaceWithMock(extraInterfaces = {Runnable.class}, defaultAnswer = Answers.RETURNS_MOCKS)
+    @Autowired
+    private InnerBean innerBean;
+
+    @Autowired
+    private OuterBeanWithAutowired outerBean;
+
+    @Test
+    @DirtiesContext
+    public void shouldUseMockInsteadOfOriginalBean() {
+        outerBean.doSomething();
+
+        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/it/SpringockitoAnnotationsComponentScanSpiesIntegrationTest.java

+package org.kubek2k.springockito.annotations.it;
+
+import org.kubek2k.springockito.annotations.SpringockitoContextLoader;
+import org.kubek2k.springockito.annotations.WrapWithSpy;