Котлин с Мокито
1. Вступление
Котлин и Ява идут рука об руку. Это означает, что мы можем использовать огромное количество существующих библиотек Java в наших проектах Kotlin.
В этой короткой статье мы увидим, как мы можем имитировать использованиеMockito в Kotlin. Если вы хотите узнать больше о библиотеке,check this article.
2. Настроить
org.mockito
mockito-all
2.0.2-beta
test
junit
junit
4.12
test
Нам также нужно сообщить Maven, что мы работаем с Kotlin, чтобы он скомпилировал для нас исходный код. Посмотритеofficial Kotlin documentation для получения дополнительной информации о том, как настроить это вpom.xml.
3. ИспользованиеMockito сKotlin
Предположим, у нас есть реализация, которую мы хотим протестировать -LendBookManager.. Этот класс имеет зависимость от службы с именемBookService, которая еще не реализована:
interface BookService {
fun inStock(bookId: Int): Boolean
fun lend(bookId: Int, memberId: Int)
}
BookService вводится во время создания экземпляраLendBookManager и используется дважды в методеcheckout, который является методом, для которого нам нужно написать наш тест:
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():
val mockBookService = Mockito.mock(BookService::class.java)
Mockito.`when`(mockBookService. inStock(100)).thenReturn(true)
Это заставит экземплярmockBookService возвращатьtrue всякий раз, когда методinStock() вызывается с аргументом 100 (обратите внимание, что нам пришлось экранировать методwhen(), используя обратную кавычку; это требуется, посколькуwhen - этоreserved keyword на языке Котлин).
Затем мы можем передать этот фиктивный экземплярLendBookManager во время создания экземпляра, вызвать метод, который мы хотим протестировать, и убедиться, что методlend() был вызван в результате операции:
val manager = LendBookManager(mockBookService)
manager.checkout(100, 1)
Mockito.verify(mockBookService).lend(100, 1)
Мы можем быстро протестировать другой логический путь реализации нашего метода, который должен вызвать исключение, если нужной книги нет в наличии:
@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)
}
Заметил, что для этого теста мыtoldmockBookService должны возвращатьfalse, когда его спрашивают, есть ли в наличии книга с идентификатором 100. Это должно привести к тому, что вызовcheckout() вызоветIllegalStateException.
Мы используем свойствоexpected в аннотации@Test, указывая на то, что мы ожидаем, что этот тест вызовет исключение.
4. MockitoKotlin Библиотека
Мы можем сделать наш код более похожим на Kotlin, используя библиотеку с открытым исходным кодом под названиемmockito-kotlin. Эта библиотека объединяет некоторые функции Mockito вокруг своих методов, обеспечивая более простой API:
@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)
}
Он также предоставляет свою версию методаmock(). При использовании этого метода мы можем использовать вывод типа, чтобы мы могли вызывать метод без передачи каких-либо дополнительных параметров.
Наконец, этоlibrary exposes a new whenever() method that can be used freely, without the need for back-ticks like we had to when using Mockito’s native when() method.
Проверьтеtheir wiki для получения полного списка улучшений.
5. Заключение
В этом кратком руководстве мы рассмотрели, как настроить наш проект для совместного использования Mockito и Kotlin, и как мы можем использовать эту комбинацию для создания макетов и написания эффективных модульных тестов.
Как всегда, вы можете ознакомиться с полным исходным кодом вGitHub repo.