Kotlin com Mockito

Kotlin com Mockito

1. Introdução

Kotlin e Java andam de mãos dadas. Isso significa que podemos aproveitar o grande número de bibliotecas Java existentes em nossos projetos Kotlin.

Neste breve artigo, veremos como podemos simular usandoMockito em Kotlin. Se você quiser aprender mais sobre a biblioteca,check this article.

2. Configuração

Em primeiro lugar, vamos criar um projetoMaven e adicionar as dependênciasJUniteMockito nopom.xml:


    org.mockito
    mockito-all
    2.0.2-beta
    test


    junit
    junit
    4.12
    test

Também precisamos informar ao Maven que estamos trabalhando com o Kotlin para que ele compile o código-fonte para nós. Verifiqueofficial Kotlin documentation para obter mais informações sobre como configurar isso empom.xml.

3. UsandoMockito comKotlin

Suponha que temos uma implementação que queremos testar -LendBookManager. Esta classe tem uma dependência de um serviço, chamadoBookService, que ainda não foi implementado:

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

OBookService é injetado durante a instanciação deLendBookManagere é usado duas vezes em todo o métodocheckout, que é o método que precisamos para escrever nosso teste para:

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

Seria difícil escrever testes de unidade para esse método sem ter a capacidade de simularBookService - que é onde o Mockito é útil.

Podemos, com apenas duas linhas de código, criar uma simulação da interfaceBookService e instruí-la a retornar um valor fixo quando o métodoinStock() for chamado:

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

Isso forçará a instânciamockBookService a retornartrue sempre que o métodoinStock() for chamado com o argumento 100 (observe que tivemos que escapar do métodowhen() usando o crase; isso é necessário, poiswhen é umreserved keyword na linguagem Kotlin).

Podemos então passar essa instância simulada paraLendBookManager durante a instanciação, invocar o método que queremos testar e verificar se o métodolend() foi chamado como resultado da operação:

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

Podemos testar rapidamente o outro caminho lógico de implementação do nosso método, que deve lançar uma exceção se o livro desejado não estiver em estoque:

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

Notei que, para este teste, nóstoldmockBookService para retornarfalse quando questionados se o livro com id 100 estava em estoque. Isso deve fazer com que a invocaçãocheckout() lance umIllegalStateException.

Usamos a propriedadeexpected na anotação@Test, indicando que esperamos que este teste lance uma exceção.

4. BibliotecaMockitoKotlin

Podemos fazer nosso código parecer mais com o Kotlin usando uma biblioteca de código aberto chamadamockito-kotlin. Esta biblioteca envolve algumas das funcionalidades do Mockito em torno de seus métodos, fornecendo uma API mais simples:

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

Ele também fornece sua versão do métodomock(). Ao usar esse método, podemos aproveitar a inferência de tipo para poder chamar o método sem passar parâmetros adicionais.

Finalmente, estelibrary 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.

Verifiquetheir wiki para uma lista completa de melhorias.

5. Conclusão

Neste tutorial rápido, vimos como configurar nosso projeto para usar o Mockito e o Kotlin juntos e como podemos aproveitar essa combinação para criar zombarias e escrever testes de unidade eficazes.

Como sempre, você pode verificar a fonte completa emGitHub repo.