12

我正在尝试@Autowired用 Mockito 模拟对象替换一个对象。执行此操作的常用方法是使用 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
}

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

你们知道让 Spring 的 JavaConfig 和 Springockito-annotations 发挥良好作用的方法吗?或者,是否有另一种创建模拟的简写?

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

4

3 回答 3

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
}
于 2015-08-06T14:19:24.613 回答
2

过时和弃用!

阅读Spring Boot 1.4 中的mocking 和 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

于 2014-01-11T22:43:53.630 回答
1

似乎SpringockitoContextLoader扩展了 GenericXmlContextLoader,它被描述为:

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

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

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

于 2013-02-19T15:05:16.130 回答