Java 模拟bean依赖项的NoSuchBeanDefinitionException
我试图在集成测试中使用mock,但运气不太好。我使用的是Spring 3.1.1和Mockito 1.9.0,情况如下:Java 模拟bean依赖项的NoSuchBeanDefinitionException,java,spring,mocking,integration-testing,mockito,cglib,Java,Spring,Mocking,Integration Testing,Mockito,Cglib,我试图在集成测试中使用mock,但运气不太好。我使用的是Spring 3.1.1和Mockito 1.9.0,情况如下: @Component public class ClassToTest { @Resource private Dependency dependency; } 及 现在,我想使用Spring的JavaConfig对ClassToTest进行集成测试。这是我尝试过的,但它不起作用: @Test @ContextConfiguration public c
@Component
public class ClassToTest {
@Resource
private Dependency dependency;
}
及
现在,我想使用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);
}
}
}
我简化了设置,使问题更容易理解。事实上,我有更多的依赖项,只想模拟其中一些依赖项——其他依赖项是真实的,基于从prod@Configuration类导入的配置
最终发生的是,我得到一个NoSuchBeanDefinitionException,表示应用程序上下文中没有NestedDependence类型的bean。我不明白这一点——我以为Spring会收到Mockito的模拟依赖实例,甚至不看它的自动连接。由于这不起作用,我最终不得不模拟我的整个对象图——这完全违背了模拟的意义
提前感谢您的帮助 Mockito在模拟类时所做的是,它使用一些奇特的名称创建一个子类,如:
依赖项$EnhancerByMockito
(IIRC)。您可能知道,子类从其父类继承字段:
@Component
public class Dependency {
@Resource
private NestedDependency nestedDependency;
}
public class Dependency$EnhancerByMockito extends Dependency{
//...
}
这意味着Spring在使用mock时仍然可以看到基类中的字段。您可以做什么:
NestedDependency
-我知道它只会将问题进一步级联一级@Resource
注释扫描我也有同样的问题,我找到了另一个解决办法。 当Spring实例化所有bean时,它将检查它是否是Mockito Mock,在本例中,我返回false for injection属性。要使用它,只需在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);
}
}
Mockito的cglib子类是否也继承私有字段???@TomMcIntyre:实际上它与Mockito/cglib无关。若创建
SubDependency扩展Dependency
普通类,Spring(通过反射)仍会找到基类中声明的私有字段。CGLIB生成的类也不例外。@Tomasz您不应该使用“继承”这个词,因为它可能会被误解。字段和方法保留在其声明类中,如果可见性修饰符允许,则可以在编译时访问这些字段和方法。在运行时,可以通过反射访问当前类或父类中的这些成员。太棒了,这让我省去了很多心痛!如果有人想知道如何注入它,请在Spring应用程序上下文XML中添加一行如下内容:
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);
}
}