我今天才开始了解莫基托。我编写了一些简单的测试(使用 JUnit,见下文) ,但是我不知道如何在 Spring 的托管 bean 中使用 mock 对象。使用 Spring 的 最佳做法是什么。我应该如何向 bean 注入模拟依赖项?
你可以跳到 回到我的问题。
首先,我所学到的。 这是一篇非常好的文章 嘲笑不是存根,它解释了基础知识(Mock 检查的是 行为验证而不是 国家核查)。这里有一个很好的例子 莫基托 这里是 更容易嘲笑。我们解释了 Mockito 的模拟对象是 嘲笑和 票根。
这个测试
@Test
public void testReal(){
List<String> mockedList = mock(List.class);
//stubbing
//when(mockedList.get(0)).thenReturn("first");
mockedList.get(anyInt());
OngoingStubbing<String> stub= when(null);
stub.thenReturn("first");
//String res = mockedList.get(0);
//System.out.println(res);
//you can also verify using argument matcher
//verify(mockedList).get(anyInt());
verify(mockedList);
mockedList.get(anyInt());
}
没问题。
回到我的问题。这里 向 Spring bean 中注入 Mockito 模拟有人试图使用 SpringReflectionTestUtils.setField()
,但这里 Spring 集成测试,创建模拟对象推荐使用 改变 Spring 的上下文。
我真的不明白最后两个链接... 谁能解释一下 Spring 和 Mockito 有什么问题?这个解决方案有什么问题吗?
@InjectMocks
private MyTestObject testObject
@Mock
private MyDependentObject mockedObject
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
Https://stackoverflow.com/a/8742745/1137529
编辑 : 我不是很清楚,我将提供3个代码示例来澄清我自己:
假设我们有具有方法 printHello()
的 bean HelloWorld 和具有方法 sayHello
的 bean HelloFacade,它们转发对 HelloWorld 方法 printHello()
的调用。
第一个例子是使用 Spring 的上下文,不使用自定义运行程序,而是对依赖注入(DI)使用 RefectionTestUtils:
public class Hello1Test {
private ApplicationContext ctx;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
this.ctx = new ClassPathXmlApplicationContext("META-INF/spring/ServicesImplContext.xml");
}
@Test
public void testHelloFacade() {
HelloFacade obj = (HelloFacade) ctx.getBean(HelloFacadeImpl.class);
HelloWorld mock = mock(HelloWorld.class);
doNothing().when(mock).printHello();
ReflectionTestUtils.setField(obj, "hello", mock);
obj.sayHello();
verify(mock, times(1)).printHello();
}
}
正如@Noam 指出的那样,有一种方法可以在不显式调用 MockitoAnnotations.initMocks(this);
的情况下运行它。在这个示例中,我还将放弃使用 Spring 的上下文。
@RunWith(MockitoJUnitRunner.class)
public class Hello1aTest {
@InjectMocks
private HelloFacade obj = new HelloFacadeImpl();
@Mock
private HelloWorld mock;
@Test
public void testHelloFacade() {
doNothing().when(mock).printHello();
obj.sayHello();
}
}
另一种方法
public class Hello1aTest {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@InjectMocks
private HelloFacadeImpl obj;
@Mock
private HelloWorld mock;
@Test
public void testHelloFacade() {
doNothing().when(mock).printHello();
obj.sayHello();
}
}
在前面的示例中,我们必须手动实例化 HelloFacadeImpl 并将其分配给 HelloFacade,因为 HelloFacade 是接口。在上一个示例中,我们只需声明 HelloFacadeImpl,Mokito 将为我们实例化它。这种方法的缺点是,目前正在测试的单元是 impl 类,而不是接口。