Kotlin with Mockito
1.简介
Kotlin和Java携手并进。这意味着我们可以在Kotlin项目中利用大量现有的Java库。
在这篇简短的文章中,我们将了解如何在Kotlin中使用Mockito进行模拟。如果您想了解有关该库的更多信息,请查看本文。
2.设定
首先,让我们创建一个Maven项目,并在pom.xml中添加JUnit和Mockito依赖项:
1 2 3 4 5 6 7 8 9 10 11 12 | <dependency> <groupId>org.mockito</groupId> mockito-core</artifactId> <version>3.3.3</version> <scope>test</scope> </dependency> <dependency> <groupId>junit</groupId> junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> |
我们还需要告诉Maven,我们正在与Kotlin合作,以便它为我们编译源代码。请查阅Kotlin官方文档,以获取有关如何在pom.xml中进行配置的更多信息。
3.与Kotlin一起使用Mockito
假设我们有一个要测试的实现– LendBookManager。此类依赖于尚未实现的名为BookService的服务:
1 2 3 4 |
BookService是在LendBookManager的实例化期间注入的,并且在整个checkout方法中使用了两次,这是我们需要为以下内容编写测试的方法:
1 2 3 4 5 6 7 8 9 | class LendBookManager(val bookService:BookService) { fun checkout(bookId: Int, memberId: Int) { if(bookService.inStock(bookId)) { bookService.lend(bookId, memberId) } else { throw IllegalStateException("Book is not available") } } } |
如果没有模拟BookService的能力,就很难为该方法编写单元测试,这正是Mockito派上用场的地方。
我们仅需两行代码,就可以创建BookService接口的模拟,并在调用inStock()方法时指示其返回固定值:
1 2 | val mockBookService = Mockito.mock(BookService::class.java) Mockito.`when`(mockBookService. inStock(100)).thenReturn(true) |
每当使用参数100调用inStock()方法时,这将强制mockBookService实例返回true(请注意,我们必须使用反引号来转义when()方法;这是必需的,因为when是Kotlin语言中的保留关键字)。
然后,我们可以在实例化过程中将此模拟实例传递给LendBookManager,调用我们要测试的方法,并验证该操作是否调用了lend()方法:
1 2 3 | val manager = LendBookManager(mockBookService) manager.checkout(100, 1) Mockito.verify(mockBookService).lend(100, 1) |
我们可以快速测试方法实现的其他逻辑路径,如果所需的书没有库存,则应该抛出异常:
1 2 3 4 5 6 7 | @Test(expected = IllegalStateException::class) fun whenBookIsNotAvailable_thenAnExceptionIsThrown() { val mockBookService = Mockito.mock(BookService::class.java) Mockito.`when`(mockBookService. inStock(100)).thenReturn(false) val manager = LendBookManager(mockBookService) manager.checkout(100, 1) } |
注意,对于该测试,当询问ID为100的书是否有存货时,我们告诉mockBookService返回false。这将导致checkout()调用引发IllegalStateException。
我们在@Test批注上使用了预期的属性,表明我们希望该测试引发异常。
4. Mockito Kotlin图书馆
我们可以使用一个名为mockito-kotlin的开源库,使代码看起来更像Kotlin。该库在其方法周围包装了Mockito的一些功能,并提供了更简单的API:
1 2 3 4 5 6 7 8 | @Test fun whenBookIsAvailable_thenLendMethodIsCalled() { val mockBookService : BookService = mock() whenever(mockBookService.inStock(100)).thenReturn(true) val manager = LendBookManager(mockBookService) manager.checkout(100, 1) verify(mockBookService).lend(100, 1) } |
它还提供了其嘲笑()方法的版本。使用此方法时,我们可以利用类型推断,因此可以在不传递任何其他参数的情况下调用该方法。
最终,该库提供了一个新的everyever()方法,该方法可以自由使用,而无需像使用Mockito的本机when()方法时那样必须使用反引号。
查看他们的Wiki以获取增强功能的完整列表。
5.结论
在本快速教程中,我们了解了如何设置项目以将Mockito和Kotlin一起使用,以及如何利用这种组合来创建模拟并编写有效的单元测试。
与往常一样,您可以在GitHub存储库中查看完整的源代码。