Kotlin avec Mockito

Kotlin avec Mockito

1. introduction

Kotlin et Java marchent main dans la main. Cela signifie que nous pouvons exploiter le grand nombre de bibliothèques Java existantes dans nos projets Kotlin.

Dans ce court article, nous allons voir comment nous pouvons nous moquer de l'utilisation deMockito dans Kotlin. Si vous souhaitez en savoir plus sur la bibliothèque,check this article.

2. Installer

Tout d'abord, créons un projetMaven et ajoutons les dépendancesJUnit etMockito dans lepom.xml:


    org.mockito
    mockito-all
    2.0.2-beta
    test


    junit
    junit
    4.12
    test

Nous devons également dire à Maven que nous travaillons avec Kotlin afin qu'il compile le code source pour nous. Consultez lesofficial Kotlin documentation pour plus d'informations sur la façon de configurer cela dans lespom.xml.

3. Utilisation deMockito avecKotlin

Supposons que nous ayons une implémentation que nous voulons tester -LendBookManager. Cette classe a une dépendance sur un service, appeléBookService, qui n'est pas encore implémentée:

interface BookService {
    fun inStock(bookId: Int): Boolean
    fun lend(bookId: Int, memberId: Int)
}

LeBookService est injecté lors de l'instanciation deLendBookManager et est utilisé deux fois tout au long de la méthodecheckout, qui est la méthode pour laquelle nous devons écrire notre test:

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")
        }
    }
}

Il serait difficile d'écrire des tests unitaires pour cette méthode sans avoir la possibilité de se moquer deBookService - c'est là que Mockito est utile.

Nous pouvons, avec seulement deux lignes de code, créer une maquette de l'interfaceBookService et lui demander de renvoyer une valeur fixe lorsque la méthodeinStock() est appelée:

val mockBookService = Mockito.mock(BookService::class.java)
Mockito.`when`(mockBookService. inStock(100)).thenReturn(true)

Cela forcera l'instancemockBookService à renvoyertrue chaque fois que la méthodeinStock() est appelée avec l'argument 100 (notez que nous avons dû échapper à la méthodewhen() en utilisant le backtick; ceci est requis puisquewhen est unreserved keyword en langage Kotlin).

Nous pouvons ensuite passer cette instance simulée àLendBookManager lors de l'instanciation, invoquer la méthode que nous voulons tester et vérifier que la méthodelend() a été appelée à la suite de l'opération:

val manager = LendBookManager(mockBookService)
manager.checkout(100, 1)
Mockito.verify(mockBookService).lend(100, 1)

Nous pouvons rapidement tester l'autre chemin logique de l'implémentation de notre méthode, qui devrait lever une exception si le livre souhaité n'est pas en stock:

@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)
}

Nous avons remarqué que, pour ce test, noustoldmockBookService pour retournerfalse quand on nous a demandé si le livre avec l'ID 100 était en stock. Cela devrait entraîner l'appel decheckout() à lancer unIllegalStateException.

Nous utilisons la propriétéexpected sur l'annotation@Test, indiquant que nous nous attendons à ce que ce test lève une exception.

4. BibliothèqueMockitoKotlin

Nous pouvons faire en sorte que notre code ressemble plus à Kotlin en utilisant une bibliothèque open-source appeléemockito-kotlin. Cette bibliothèque englobe certaines des fonctionnalités de Mockito autour de ses méthodes, fournissant une API plus simple:

@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)
}

Il fournit également sa version de la méthodemock(). Lors de l'utilisation de cette méthode, nous pouvons tirer parti de l'inférence de type pour pouvoir appeler la méthode sans transmettre de paramètres supplémentaires.

Enfin, celibrary 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.

Vérifieztheir wiki pour une liste complète des améliorations.

5. Conclusion

Dans ce rapide didacticiel, nous avons examiné comment configurer notre projet pour utiliser Mockito et Kotlin ensemble, et comment utiliser cette combinaison pour créer des simulacres et écrire des tests unitaires efficaces.

Comme toujours, vous pouvez consulter la source complète dans lesGitHub repo.