将mock注入不带xml的Spring容器进行测试

时间:2011-05-09 09:39:57

标签: java spring mocking mockito

目前我使用@Autowired,@ Component,@ Resource等连接了我的spring应用程序。现在我想编写一个测试,它需要模拟系统中的特定对象,但保留其余对象的实际生产线。

假设正在测试的根对象名为 Foo 。更深入的依赖链,Foo依赖于Bar。目前为了模拟这个对象,我创建了一个test-applicationContext.xml,它只包含单个bean条目:

<bean id="bar" class="org.mockito.Mockito" factory-method="mock"> 
    <constructor-arg value="com.package.Bar" /> 
</bean>

test-applicationContext.xml在@ContextConfiguration注释中声明,因此Foo最终将依赖于模拟的Bar对象。

是否可以在不必拥有此test-applicationContext.xml的情况下获得相同的结果?即做同样的但是有进步的吗?

所以在伪代码中,我想知道我是否可以拥有类似的东西:

public class MyTest {

    @Test
    public void simple() {
        // create mock Bar object
        // register mock Bar object in container
        // resolve Foo object with all its dependencies but use the mock Bar object instead of the real one
        // set some expectations on the Bar object
        // call some method on Foo
    }
}

3 个答案:

答案 0 :(得分:3)

您必须避免在单元测试中启动Spring上下文。仅在检查属性注入和其他Spring功能的测试中使用Spring上下文。然后,您将能够以编程方式创建模拟对象。

尽管如此,可以通过以下方式完成:

  BeanDefinitionRegistry registry = ((BeanDefinitionRegistry )factory);

  GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
  beanDefinition.setBeanClass(MyBeanClass.class);
  beanDefinition.setLazyInit(false);
  beanDefinition.setAbstract(false);
  beanDefinition.setAutowireCandidate(true);
  beanDefinition.setScope("session");

  registry.registerBeanDefinition("dynamicBean",beanDefinition);

只需在您的JUnit中注入BeanFactory即可获得工厂

答案 1 :(得分:0)

一种方法:

  1. 在测试环境中,组件扫描最低限度。

  2. @Autowire Bar的依赖关系到您的测试类。

  3. 在你的设置中:

    1. 手动new Bar()

    2. 创建Foo模拟

    3. 设置新栏的属性,包括@Autowired(第一个#2)和模拟(第二个#2)。

答案 2 :(得分:0)

我遇到了一个非常类似的问题并使用了https://bitbucket.org/kubek2k/springockito/wiki/Home,这对我来说非常重要。

在你的情况下你可以使用如果你想要完全模拟然后使用@ReplaceWithMock,或者你可以使用@WrapWithSpy进行部分模拟,只有你可以模拟你想要改变行为的函数。