3

我试图在我的集成测试中使用模拟并且运气不佳。我使用的是Spring 3.1.1和Mockito 1.9.0,情况如下:

@Component
public class ClassToTest {

    @Resource
    private Dependency dependency;

}

@Component
public class Dependency {

    @Resource
    private NestedDependency nestedDependency;

}

现在,我想使用 Spring 的 JavaConfig 对 ClassToTest 进行集成测试。这是我尝试过的,但它不起作用:

@Test
@ContextConfiguration
public class ClassToTestIntegrationTest {

    @Resource
    private ClassToTest classToTest;

    @Resource
    private Dependency mockDependency;

    @Test
    public void someTest() {
        verify(mockDependency).doStuff();

        // other Mockito magic...

    }


    @Configuration
    static class Config {

        @Bean
        public ClassToTest classToTest() {
            return new ClassToTest();
        }

        @Bean
        public Dependency dependency() {
            return Mockito.mock(Dependency.class);
        }

    }
}

我已经简化了我的设置,使问题更容易理解。实际上,我有更多依赖项,只想模拟其中的一些依赖项——其他依赖项是真实的,基于从我的产品 @Configuration 类导入的配置。

最终发生的事情是我得到一个 NoSuchBeanDefinitionException ,说应用程序上下文中没有 NestedDependency 类型的 bean。我不明白这一点 - 我认为 Spring 会收到 Mockito 的 Dependency 模拟实例,甚至不考虑自动装配它。由于这不起作用,我最终不得不模拟我的整个对象图——这完全违背了模拟的意义!

提前感谢您的帮助!

4

2 回答 2

5

我有同样的问题,我找到了另一个解决方案。当 Spring 实例化所有 bean 时,它会检查它是否是 Mockito Mock,在这种情况下,我为注入属性返回 false。要使用它,只需在 Spring 上下文中注入它

下面的代码:

public class MockBeanFactory extends InstantiationAwareBeanPostProcessorAdapter {

    private static final MockUtil mockUtil = new MockUtil();

    public MockBeanFactory() {
        super();
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return !mockUtil.isMock(bean);
    }

}
于 2013-02-08T10:18:49.667 回答
2

Mockito 在模拟类时所做的是它使用创建一个子类,该子类具有一些花哨的名称,例如:Dependency$EnhancerByMockito(IIRC)。您可能知道,子类从其父类继承字段:

@Component
public class Dependency {

    @Resource
    private NestedDependency nestedDependency;

}


public class Dependency$EnhancerByMockito extends Dependency{
    //...
}

这意味着 Spring 在使用 mock 时仍然可以看到基类中的字段。你可以做什么:

  1. 使用接口,这将导致 Mockito 使用动态代理而不是 CGLIB 生成的类

  2. 模拟NestedDependency- 我知道它只会将问题进一步级联

  3. 为测试禁用@Resource注释扫描

于 2012-04-10T20:23:57.640 回答