使用Mockito测试课程
Mockito是用于Java编写的单元测试的通用模拟框架。该框架允许在自动化单元测试中创建模拟对象,以实现测试驱动开发 (TDD)。这些模拟测试框架有效地“伪造”了一些外部依赖项,以便被测试的对象与其外部依赖项具有一致的交互。Mockito致力于简化这些测试附带的外部依赖项的交付。因此,Mockito 可帮助您构建可维护的高质量测试,从而实现持续交付。
当您将“单元”缩小为基本的面向对象元素(即类)时,您可能会单独使用 Mockito。您将模拟该类的所有依赖项,只留下该类的逻辑进行测试。
单元(班级)测试
通过单元测试,我们将应用程序中的每个元素与其他元素隔离开来。如前所述,当新书添加到图书馆时,我们会将其存储到数据库中并向读者发送通知。Library类中newBook方法的实现同时使用了库 DAL 和 reader 服务,如下所示:
public void newBook(String bookName, String author) { … // Add the new book to the database: String bookId = libraryDal.storeBook(bookName, author); … // Inform readers about the new book: readersService.newBookAdded(bookId, bookName, author); ... }
测试不关心图书馆 DAL 或读者服务做什么以及它们是否正确执行。它只需要验证,在给定特定书名和特定作者的情况下,是否进行了适当的数据库插入并正确通知读者服务。
为了实现这一目标,我们需要使用模拟真实库 DAL 和读者服务实现的模拟。使用适当的Mockito注释,Mockito知道扫描被测类并用代理替换类依赖项(类成员),代理以测试作者希望它们响应的方式进行响应。Mockito将模拟“注入”到测试类中。
以下代码说明了这一点:
@InjectMocks private LibraryImpl library; @Mock private LibraryDal libraryDal; @Mock private ReadersService readersService; @Before public void init() { // Inject mocks to the library class: MockitoAnnotations.initMocks(this); // Return book id upon book name and author: doAnswer(new Answer() { ? ??@Override ? ??public Object answer(InvocationOnMock invocationOnMock) throws Throwable ? ??{ ? ? ? ??Object[] arguments = invocationOnMock.getArguments(); ? ? ? ??return "BookId_" + arguments[0].toString() + "_" + arguments[1].toString(); ? ??} }).when(libraryDal).storeBook(anyString(), anyString()); }
现在我们可以测试我们的库类是否按预期执行和调用其他元素(DAL 和阅读器服务):
@Test public void testNotification() { // Test the new book method: library.newBook("The Trial", "Kafka"); // Verify we stored the book in the database and called the readers service: verify(libraryDal, times(1)).storeBook("The Trial", "Kafka"); verify(readersService, times(1)).newBookAdded("BookId_The Trial_Kafka", "The Trial", "Kafka"); }
我们可以使用相同的机制来测试其他应用程序组件。我们将模拟它们的依赖关系,并验证在给定特定输入的情况下,它们执行特定流程并生成特定输出。
|