使用Spring JavaConfig和@Autowired注入Mockito Mock对象

时间:2013-02-15 13:39:14

标签: java spring integration-testing mockito spring-java-config

我正在尝试用Mockito模拟对象替换@Autowired对象。通常的方法是使用Springockito使用xml:

<mockito:mock id="SomeMock" class="com.package.MockInterface" />

目前我正在尝试使用Spring的JavaConfig来完成这项工作。突然之间,Java表达式比xml更加冗长:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class MyTestClass {

    @Configuration
    static class Config {
        @Bean
        public MockInterface somethingSpecial() {
            return Mockito.mock(MockInterface.class);
        }
    }

    @Autowired MockInterface mockObj;

    // test code
}

我发现了一个名为Springockito-annotations的库,它允许您执行以下操作:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader=SpringockitoContextLoader.class)
public class MyTestClass {

    @Autowired @ReplaceWithMock MockInterface mockObj;

    // test code
}

显然,一大堆更漂亮:)唯一的问题是这个上下文加载器不允许我对其他bean使用@Configuration和JavaConfig(如果我这样做,Spring抱怨没有匹配的候选者那些自动装配的领域。)

你们有没有办法让Spring的JavaConfig和Springockito-annotations发挥得淋漓尽致?或者,是否有另一种创建模拟的简写?

作为一个很好的奖励,使用Springockito和xml配置,我能够模拟出具体的类,而不为它的依赖项提供自动装配候选(如果有的话)。如果没有xml,这是不可能的吗?

3 个答案:

答案 0 :(得分:4)

离开现在没有维护的(在撰写本文时)Spingockito-annotations和Mockito,我们有一种非常简单的方法:

@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {

    @Mock MockInterface mockObj;

    // test code
}

如果您正在使用真实对象,但想在其中模拟依赖项,例如使用DAO测试服务层:

@RunWith(MockitoJUnitRunner.class)
@ContextConfiguration
public class MyTestClass {

    @InjectMocks RealService;

    @Mock MockDAO mockDAO;

    // test code
}

最后,这也可以应用于Spring-boot,但在setUp()中使用注释初始化,直到支持多个类运行器:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = MyMainSpringBootClass.class)
public class MyTestClass {

    @InjectMocks RealService;

    @Mock MockDAO mockDAO;

    @Before
    public final void setUp() throws Exception{
        MockitoAnnotations.initMocks(this);
    }

    // test code
}

答案 1 :(得分:2)

已过时且已弃用!

阅读Spring Boot 1.4中的mocking and spying

请同时阅读@ethesx的答案, Springockito未经维护

旧答案

现在可以在没有Springockito-annotations的任何XML文件的情况下模拟Spring应用程序。此解决方案也适用于Spring Boot

import static org.mockito.BDDMockito.*;
import org.kubek2k.springockito.annotations.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = Application.class, 
     loader = SpringockitoAnnotatedContextLoader.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class MainControllerTest {

    @Autowired
    MainController mainController;

    @Autowired
    @ReplaceWithMock
    FooService fooService;

    @Test
    public void shouldGetBar() {
        //given
        given(fooService.result("foo")).willReturn("bar");

        //when
        Bar bar build = fooService.getBar("foo");

        //then
        assertThat(bar).isNotNull();
    }
}

依赖关系:org.kubek2k:springockito-annotations:1.0.9

答案 2 :(得分:1)

SpringockitoContextLoader似乎延伸了GenericXmlContextLoader,其描述为:

  

AbstractGenericContextLoader的具体实现,它从XML资源中读取bean定义。

因此,目前您仅限于xml bean定义。

您可以编写自己的上下文加载器,从SpringockitoContextLoader类中获取相关部分。看看here开始,也许你可以扩展AnnotationConfigContextLoader例如?