@InjectMocks 在自动装配其余依赖项时不起作用
@InjectMocks not working while Autowiring rest of dependencies
我正在尝试测试使用 2 项服务的 ClassA
。一项服务需要自动装配,而另一项服务则被视为模拟对象。不幸的是,模拟对象是
not injected
到我的测试class。所有字段的行为就像我只会使用 spring 自动装配功能来设置它一样。经过测试 ClassA 也继承自其他抽象 class。如果不使用自动装配,模拟对象将成功传递。不幸的是我不能嘲笑 ServiceDao,这就是为什么我试图结合 @InjectMocks
和 @Autowiring
注释。
Class A.
public ClassA extends AbstractClassA<ClassOne, ClassTwo>{
@Autowired
protected ServiceOne serviceOne; //this services needs to be mocked
@Override
protected List<ClassTwo> testedMethod(){
return serviceOne.getList(); //here method is not returning mocked objects
} //as it supposed to do.
........
}
摘要Class
public class AbstractClassA<T1 extends InterfaceOne, T2 extends InterfaceTwo){
@Autowired
protected ServiceDAO serviceDAO; //this services needs to be autowired
protected abstract List<T2> testedMethod();
}
测试Class.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class Test {
@Mock
private ServiceOne serviceOne; //this mock object and it's return
//objects are set properly
@Autowired
@InjectMocks
private ClassA classA; //all fields are autowired, including the services that should be mocked
@Before
public void setData(){
Mockito.Annotations.initMocks(this);
List<ClassTwo> result = Arrays.asList(new ClassA());
when(serviceOne.testedMethod().thenReturn(result); //here when i invoke mocked object it is returning correct list.
}
}
在这种情况下,最好通过 Spring 测试上下文配置模拟注入的 bean。如果您无法轻松做到这一点,您可以使用 Springs ReflectionTestUtils class 来模拟服务中的单个对象。
在您的测试配置 XML 文件中,您可以定义一个模拟 bean:
<bean id="serviceOne" class="org.mockito.Mockito" factory-method="mock"/>
<constructor-arg value="com.package.ServiceOne"/>
</bean>
在Java侧:
@Bean
public ServiceOne serviceOne() {
return mock(ServiceOne.class);
}
在您的测试用例中,您可以 @Autowire ServiceOne serviceOne
并将其用作模拟对象:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class Test {
@Autowired
private ServiceOne serviceOne;
@Autowired
private ClassA classA;
@Before
public void setData(){
Mockito.Annotations.initMocks(this);
List<ClassTwo> result = Arrays.asList(new ClassA());
when(serviceOne.testedMethod()).thenReturn(result);
}
}
我正在尝试测试使用 2 项服务的 ClassA
。一项服务需要自动装配,而另一项服务则被视为模拟对象。不幸的是,模拟对象是
not injected
到我的测试class。所有字段的行为就像我只会使用 spring 自动装配功能来设置它一样。经过测试 ClassA 也继承自其他抽象 class。如果不使用自动装配,模拟对象将成功传递。不幸的是我不能嘲笑 ServiceDao,这就是为什么我试图结合 @InjectMocks
和 @Autowiring
注释。
Class A.
public ClassA extends AbstractClassA<ClassOne, ClassTwo>{
@Autowired
protected ServiceOne serviceOne; //this services needs to be mocked
@Override
protected List<ClassTwo> testedMethod(){
return serviceOne.getList(); //here method is not returning mocked objects
} //as it supposed to do.
........
}
摘要Class
public class AbstractClassA<T1 extends InterfaceOne, T2 extends InterfaceTwo){
@Autowired
protected ServiceDAO serviceDAO; //this services needs to be autowired
protected abstract List<T2> testedMethod();
}
测试Class.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class Test {
@Mock
private ServiceOne serviceOne; //this mock object and it's return
//objects are set properly
@Autowired
@InjectMocks
private ClassA classA; //all fields are autowired, including the services that should be mocked
@Before
public void setData(){
Mockito.Annotations.initMocks(this);
List<ClassTwo> result = Arrays.asList(new ClassA());
when(serviceOne.testedMethod().thenReturn(result); //here when i invoke mocked object it is returning correct list.
}
}
在这种情况下,最好通过 Spring 测试上下文配置模拟注入的 bean。如果您无法轻松做到这一点,您可以使用 Springs ReflectionTestUtils class 来模拟服务中的单个对象。
在您的测试配置 XML 文件中,您可以定义一个模拟 bean:
<bean id="serviceOne" class="org.mockito.Mockito" factory-method="mock"/>
<constructor-arg value="com.package.ServiceOne"/>
</bean>
在Java侧:
@Bean
public ServiceOne serviceOne() {
return mock(ServiceOne.class);
}
在您的测试用例中,您可以 @Autowire ServiceOne serviceOne
并将其用作模拟对象:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:testApplicationContext.xml"})
public class Test {
@Autowired
private ServiceOne serviceOne;
@Autowired
private ClassA classA;
@Before
public void setData(){
Mockito.Annotations.initMocks(this);
List<ClassTwo> result = Arrays.asList(new ClassA());
when(serviceOne.testedMethod()).thenReturn(result);
}
}