Injecting Mockito mocks into a Spring bean

后端 未结 22 1179
庸人自扰
庸人自扰 2020-11-22 09:44

I would like to inject a Mockito mock object into a Spring (3+) bean for the purposes of unit testing with JUnit. My bean dependencies are currently injected by using the

相关标签:
22条回答
  • 2020-11-22 10:24

    If you're using spring >= 3.0, try using Springs @Configuration annotation to define part of the application context

    @Configuration
    @ImportResource("com/blah/blurk/rest-of-config.xml")
    public class DaoTestConfiguration {
    
        @Bean
        public ApplicationService applicationService() {
            return mock(ApplicationService.class);
        }
    
    }
    

    If you don't want to use the @ImportResource, it can be done the other way around too:

    <beans>
        <!-- rest of your config -->
    
        <!-- the container recognize this as a Configuration and adds it's beans 
             to the container -->
        <bean class="com.package.DaoTestConfiguration"/>
    </beans>
    

    For more information, have a look at spring-framework-reference : Java-based container configuration

    0 讨论(0)
  • 2020-11-22 10:27

    Update - new answer here: https://stackoverflow.com/a/19454282/411229. This answer only applies to those on Spring versions before 3.2.

    I've looked for a while for a more definitive solution to this. This blog post seems to cover all my needs and doesn't rely on ordering of bean declarations. All credit to Mattias Severson. http://www.jayway.com/2011/11/30/spring-integration-tests-part-i-creating-mock-objects/

    Basically, implement a FactoryBean

    package com.jayway.springmock;
    
    import org.mockito.Mockito;
    import org.springframework.beans.factory.FactoryBean;
    
    /**
     * A {@link FactoryBean} for creating mocked beans based on Mockito so that they 
     * can be {@link @Autowired} into Spring test configurations.
     *
     * @author Mattias Severson, Jayway
     *
     * @see FactoryBean
     * @see org.mockito.Mockito
     */
    public class MockitoFactoryBean<T> implements FactoryBean<T> {
    
        private Class<T> classToBeMocked;
    
        /**
         * Creates a Mockito mock instance of the provided class.
         * @param classToBeMocked The class to be mocked.
         */
        public MockitoFactoryBean(Class<T> classToBeMocked) {
            this.classToBeMocked = classToBeMocked;
        }
    
        @Override
        public T getObject() throws Exception {
            return Mockito.mock(classToBeMocked);
        }
    
        @Override
        public Class<?> getObjectType() {
            return classToBeMocked;
        }
    
        @Override
        public boolean isSingleton() {
            return true;
        }
    }
    

    Next update your spring config with the following:

    <beans...>
        <context:component-scan base-package="com.jayway.example"/>
    
        <bean id="someDependencyMock" class="com.jayway.springmock.MockitoFactoryBean">
            <constructor-arg name="classToBeMocked" value="com.jayway.example.SomeDependency" />
        </bean>
    </beans>
    
    0 讨论(0)
  • 2020-11-22 10:27

    Looking at Springockito pace of development and number of open issues, I would be little bit worried to introduce it into my test suite stack nowadays. Fact that last release was done before Spring 4 release brings up questions like "Is it possible to easily integrate it with Spring 4?". I don't know, because I didn't try it. I prefer pure Spring approach if I need to mock Spring bean in integration test.

    There is an option to fake Spring bean with just plain Spring features. You need to use @Primary, @Profile and @ActiveProfiles annotations for it. I wrote a blog post on the topic.

    0 讨论(0)
  • 2020-11-22 10:27
    <bean id="mockDaoFactory" name="dao" class="com.package.test.MocksFactory">
        <property name="type" value="com.package.Dao" />
    </bean>
    

    this ^ works perfectly well if declared first/early in the XML file. Mockito 1.9.0/Spring 3.0.5

    0 讨论(0)
提交回复
热议问题