我在我的代码中使用Spring注释来执行DI。所以假设我有一个依赖于另一个类class2的类class1,我将class1定义如下:
@Component
public class class1 {
@Resource
private interface2 object2;
}
class2是interface2的一个实现。
现在假设我想模拟class2并将其传递给class1,我在class1中看不到任何构造函数或setter。我认为Spring使用反射来注入object2。我怎么嘲笑它?我应该在class1中添加一个setter吗?或者我可以像Spring一样重复使用它 - 我的意思是spring本身有一个模拟对象框架或者什么,我打算使用EasyMock进行模拟。
由于
答案 0 :(得分:6)
春天的ReflectionTestUtils class可能会有所帮助 它似乎做你正在寻找的......至少注射部分: - )
答案 1 :(得分:3)
Mockito有一个非常强大的方法来处理模拟和DI:
@RunWith(MockitoJUnitRunner.class)
public class Class1Test {
@Mock
private Interface2 inteface2mock;
@InjectMocks
private Class1 class1;
@Test
public void someTest() {
when(interface2mock.doSomething("arg")).thenReturn("result");
String actual = class1.doSomeThatDelegatesToInterface2();
assertEquals("result", actual);
}
}
详细了解Mockito javadoc中的@InjectMocks或我前一段时间撰写的有关该主题的blog post。
从Mockito 1.8.3开始,在1.9.0中增强。
答案 2 :(得分:1)
ReflectionTestUtils是最容易添加你想要的模拟(我们使用JMock,但它并不重要),缺点是它稍微脆弱。如果重命名该字段,则必须记住也要更改测试。
您也可以使用此:http://i-proving.com/2006/11/09/using-jmock-and-inject-object/
它描述了如何在spring上下文中使用模拟对象。
答案 3 :(得分:0)
AFAIK,Spring中没有内置的模拟框架,所以你需要使用像EasyMock这样的东西。我过去这样做的方式是
appContext-main.xml
中定义,测试配置(模拟对象)在appContext-test.xml
中定义appContext-test.xml
中的模拟bean必须与appContext-main.xml
appContext-main.xml
时appContext-main.xml
和appContext-test.xml
都会加载。确保它们按此顺序加载,以便模拟“覆盖”任何同名的bean *您无需将所有 Spring配置转换为XML即可使用此方法。只有那些具有模拟实现或注入模拟实现的bean才需要更改。其他bean可以继续使用注释进行定义。
答案 4 :(得分:0)
通过反射注入自己很容易,所以你可以避免使用setter方法。
自己做就是这样:
for (Field field : injectable.getClass().getDeclaredFields()) {
MyAnnotation annotation = field.getAnnotation(MyAnnotation.class);
if (annotation != null) {
field.setAccessible(true);
Object param = generateMockObject();
field.set(injectable, param);
}
}
答案 5 :(得分:0)
有一个JUnit规则,以Mockito的方式为EasyMock提供类似的注释驱动注入功能。见EasyMockRule