【问题标题】:Injecting mock into Spring container without xml for testing在没有xml的情况下将mock注入Spring容器进行测试
【发布时间】:2011-05-09 09:39:57
【问题描述】:

目前,我使用@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
    }
}

【问题讨论】:

    标签: java spring mocking mockito


    【解决方案1】:

    您必须避免在单元测试中启动 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);
    

    只需将 BeanFactory 注入 JUnit 即可获得工厂

    【讨论】:

      【解决方案2】:

      一种方法:

      1. 在您的测试环境中,组件扫描最少。

      2. @Autowire 将 Bar 的依赖项自动连接到您的测试类中。

      在您的设置中:

      1. 手动new Bar()

      2. 创建 Foo 的模拟

      3. 设置新 Bar 的属性,包括 @Autowired(第一个 #2)和 mock(第二个​​ #2)。

      【讨论】:

        【解决方案3】:

        我遇到了一个非常相似的问题并使用了https://bitbucket.org/kubek2k/springockito/wiki/Home,这对我来说真的很有帮助。

        在您的情况下,如果您想要完全模拟,则可以使用 @ReplaceWithMock 或者您可以使用 @WrapWithSpy 进行部分模拟,并且只有您可以模拟您想要更改其行为的函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2023-04-04
          • 2010-11-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多