Atualização em setembro de 2019: A única estrutura de simulação suportada (por padrão) pelo Spring Boot é o Mockito . Se você usa o Spring, a resposta é bastante óbvia.
Eu diria que a competição é entre JMockit e PowerMock , depois Mockito .
Eu deixaria o jMock e o EasyMock "simples" porque eles usam apenas proxy e CGLIB e não usam a instrumentação Java 5 como as estruturas mais recentes.
O jMock também não possui uma versão estável há mais de 4 anos. O jMock 2.6.0 exigiu 2 anos para passar de RC1 para RC2 e mais 2 anos antes de ser lançado.
Em relação ao Proxy e CGLIB vs instrumentação:
(EasyMock e jMock) são baseados em java.lang.reflect.Proxy, que requer que uma interface seja implementada. Além disso, eles suportam a criação de objetos simulados para classes através da geração de subclasse CGLIB. Por esse motivo, as referidas classes não podem ser finais e apenas métodos de instância substituíveis podem ser ridicularizados. Mais importante, no entanto, ao usar essas ferramentas, as dependências do código em teste (ou seja, os objetos de outras classes das quais depende uma determinada classe em teste) devem ser controladas pelos testes, para que instâncias simuladas possam ser transmitidas aos clientes dessas dependências. Portanto, as dependências não podem simplesmente ser instanciadas com o novo operador em uma classe cliente para a qual queremos escrever testes de unidade.
Por fim, as limitações técnicas das ferramentas de simulação convencionais impõem as seguintes restrições de design no código de produção:
- Cada classe que pode precisar ser ridicularizada em um teste deve implementar uma interface separada ou não ser final.
- As dependências de cada classe a ser testada devem ser obtidas por meio de métodos configuráveis de criação de instância (fábricas ou um Localizador de Serviço) ou expostas para injeção de dependência. Caso contrário, os testes de unidade não poderão passar implementações simuladas de dependências para a unidade em teste.
- Como apenas métodos de instância podem ser zombados, as classes a serem testadas em unidade não podem chamar métodos estáticos em suas dependências, nem instancia-las usando qualquer um dos construtores.
O acima é copiado de http://jmockit.org/about.html . Além disso, ele compara entre si (JMockit), PowerMock e Mockito de várias maneiras:
Agora existem outras ferramentas de simulação para Java que também superam as limitações das convencionais, entre elas PowerMock, jEasyTest e MockInject. O que mais se aproxima do conjunto de recursos do JMockit é o PowerMock, então eu o avaliarei brevemente aqui (além disso, os outros dois são mais limitados e não parecem mais ser desenvolvidos ativamente).
JMockit vs PowerMock
- Primeiro, o PowerMock não fornece uma API completa para zombaria, mas funciona como uma extensão para outra ferramenta, que atualmente pode ser EasyMock ou Mockito. Obviamente, isso é uma vantagem para os usuários existentes dessas ferramentas.
- O JMockit, por outro lado, fornece APIs totalmente novas, embora sua API principal (Expectativas) seja semelhante ao EasyMock e ao jMock. Embora isso crie uma curva de aprendizado mais longa, também permite que o JMockit forneça uma API mais simples, consistente e fácil de usar.
- Comparada à API do JMockit Expectations, a API do PowerMock é mais "de baixo nível", forçando os usuários a descobrir e especificar quais classes precisam ser preparadas para teste (com a anotação @PrepareForTest ({ClassA.class, ...}) ) e exigindo chamadas de API específicas para lidar com vários tipos de construções de linguagem que podem estar presentes no código de produção: métodos estáticos (mockStatic (ClassA.class)), construtores (suprimir (construtor (ClassXyz.class))), invocações de construtores ( expectNew (AClass.class)), simulações parciais (createPartialMock (ClassX.class, "methodToMock"))) etc.
- Com o JMockit Expectations, todos os tipos de métodos e construtores são zombados de maneira puramente declarativa, com zombarias parciais especificadas por meio de expressões regulares na anotação @Mocked ou simplesmente "zombando" dos membros sem expectativas registradas; ou seja, o desenvolvedor simplesmente declara alguns "campos simulados" compartilhados para a classe de teste ou alguns "campos simulados locais" e / ou "parâmetros simulados" para métodos de teste individuais (e, neste último caso, a anotação @Mocked geralmente não necessário).
- Alguns recursos disponíveis no JMockit, como suporte para zombar de iguais e hashCode, métodos substituídos e outros, atualmente não são suportados no PowerMock. Além disso, não há equivalente à capacidade do JMockit de capturar instâncias e implementações simuladas de tipos de base especificados à medida que o teste é executado, sem que o próprio código de teste tenha conhecimento das classes de implementação reais.
- O PowerMock usa carregadores de classes personalizados (geralmente um por classe de teste) para gerar versões modificadas das classes simuladas. Esse uso pesado de carregadores de classe personalizados pode levar a conflitos com bibliotecas de terceiros, portanto, às vezes, é necessário usar a anotação @PowerMockIgnore ("package.to.be.ignored") nas classes de teste.
- O mecanismo usado pelo JMockit (instrumentação de tempo de execução por meio de um "agente Java") é mais simples e seguro, embora exija a passagem de um parâmetro "-javaagent" para a JVM durante o desenvolvimento no JDK 1.5; no JDK 1.6+ (que sempre pode ser usado para desenvolvimento, mesmo que a implementação em uma versão mais antiga) não existe esse requisito, pois o JMockit pode carregar de forma transparente o agente Java sob demanda usando a API Attach.
Outra ferramenta de zombaria recente é o Mockito. Embora não tente superar as limitações das ferramentas mais antigas (jMock, EasyMock), ele introduz um novo estilo de teste de comportamento com zombarias. O JMockit também suporta esse estilo alternativo, por meio da API de verificações.
JMockit vs Mockito
- O Mockito depende de chamadas explícitas à sua API para separar o código entre as fases de registro (quando (...)) e verificação (verificação (...)). Isso significa que qualquer chamada para um objeto simulado no código de teste também exigirá uma chamada para a API de simulação. Além disso, isso geralmente leva a chamadas repetitivas quando (...) e verifica (zomba) ...
- Com o JMockit, não há chamadas semelhantes. Certamente, temos as novas chamadas de construtor NonStrictExpectations () e Verifications (), mas elas ocorrem apenas uma vez por teste (normalmente) e são completamente separadas das invocações para métodos e construtores simulados.
- A API do Mockito contém várias inconsistências na sintaxe usada para invocações para métodos simulados. Na fase de registro, temos chamadas como when (mock.mockedMethod (args)) ... enquanto na fase de verificação essa mesma chamada será gravada como Verifique (mock) .mockedMethod (args). Observe que, no primeiro caso, a chamada para mockedMethod é feita diretamente no objeto simulado, enquanto no segundo caso, é feita no objeto retornado pela verificação (simulação).
- O JMockit não possui essas inconsistências porque as invocações para métodos simulados são sempre feitas diretamente nas próprias instâncias simuladas. (Com apenas uma exceção: para combinar chamadas na mesma instância simulada, uma chamada onInstance (mock) é usada, resultando em código como onInstance (mock) .mockedMethod (args); a maioria dos testes não precisará usar isso. )
- Assim como outras ferramentas de simulação que dependem do encadeamento / encapsulamento de métodos, o Mockito também apresenta uma sintaxe inconsistente ao remover métodos anulados. Por exemplo, você escreve when (mockedList.get (1)). ThenThrow (new RuntimeException ()); para um método não nulo e doThrow (new RuntimeException ()). when (mockedList) .clear (); por um vazio. Com o JMockit, é sempre a mesma sintaxe: mockedList.clear (); resultado = nova RuntimeException () ;.
- Ainda outra inconsistência ocorre no uso de espiões de Mockito: "zombarias" que permitem que os métodos reais sejam executados na instância de espionagem. Por exemplo, se spy refere-se a uma lista vazia, em vez de escrever when (spy.get (0)). ThenReturn ("foo"), você precisará escrever doReturn ("foo"). When (spy) .get ( 0) Com o JMockit, o recurso de zombaria dinâmica fornece funcionalidade semelhante aos espiões, mas sem esse problema, pois os métodos reais são executados apenas durante a fase de reprodução.
- No EasyMock e no jMock, as primeiras APIs de simulação para Java, o foco era inteiramente o registro de chamadas esperadas de métodos simulados, para objetos simulados que (por padrão) não permitem invocações inesperadas. Essas APIs também fornecem a gravação de invocações permitidas para objetos simulados que permitem invocações inesperadas, mas isso foi tratado como um recurso de segunda classe. Além disso, com essas ferramentas, não há como verificar explicitamente as invocações para zombarias após o exercício do código em teste. Todas essas verificações são realizadas de forma implícita e automática.
- No Mockito (e também no Unitils Mock), o ponto de vista oposto é adotado. Todas as invocações para zombar de objetos que possam ocorrer durante o teste, gravadas ou não, são permitidas, nunca esperadas. A verificação é realizada explicitamente depois que o código em teste é exercido, nunca automaticamente.
- Ambas as abordagens são muito extremas e, consequentemente, inferiores ao ideal. O JMockit Expectations & Verifications é a única API que permite ao desenvolvedor escolher perfeitamente a melhor combinação de invocações simuladas estritas (esperadas por padrão) e não estritas (permitidas por padrão) para cada teste.
- Para ser mais claro, a API do Mockito tem as seguintes deficiências. Se você precisar verificar se uma chamada para um método simulado não nulo ocorreu durante o teste, mas o teste exigir um valor de retorno daquele método diferente do padrão para o tipo de retorno, o teste de Mockito terá código duplicado: uma chamada when (mock.someMethod ()). thenReturn (xyz) na fase de registro e uma verificação (mock) .someMethod () na fase de verificação. Com o JMockit, uma expectativa estrita sempre pode ser registrada, o que não precisará ser verificado explicitamente. Como alternativa, uma restrição de contagem de chamadas (vezes = 1) pode ser especificada para qualquer expectativa não estrita registrada (com o Mockito essas restrições podem ser especificadas apenas em uma chamada de verificação (simulação, restrição)).
- O Mockito possui uma sintaxe ruim para verificações em ordem e para verificações completas (ou seja, verificar se todas as chamadas para objetos simulados são explicitamente verificadas). No primeiro caso, um objeto extra precisa ser criado e as chamadas para verificação são feitas: InOrder inOrder = inOrder (mock1, mock2, ...). No segundo caso, é necessário fazer chamadas como confirmNoMoreInteractions (mock) ou confirmZeroInteractions (mock1, mock2).
- Com o JMockit, você simplesmente escreve novas VerificationsInOrder () ou novas FullVerifications () em vez de novas Verifications () (ou novas FullVerificationsInOrder () para combinar os dois requisitos). Não há necessidade de especificar quais objetos simulados estão envolvidos. Nenhuma chamada API de zombaria extra. E como bônus, chamando unverifiedInvocations () dentro de um bloco de verificação ordenado, você pode executar verificações relacionadas a pedidos que são simplesmente impossíveis no Mockito.
Por fim, o JMockit Testing Toolkit tem um escopo mais amplo e objetivos mais ambiciosos do que outros kits de ferramentas de simulação, a fim de fornecer uma solução completa e sofisticada de teste de desenvolvedor. Uma boa API para zombaria, mesmo sem limitações artificiais, não é suficiente para a criação produtiva de testes. Uma ferramenta de cobertura de código independente do IDE, fácil de usar e bem integrada também é essencial, e é isso que o JMockit Coverage visa fornecer. Outra parte do conjunto de ferramentas de teste do desenvolvedor que se tornará mais útil à medida que o conjunto de testes aumenta de tamanho é a capacidade de executar novamente testes de forma incremental após uma alteração localizada no código de produção; isso também está incluído na ferramenta Cobertura.
(concedido, a fonte pode ser tendenciosa, mas bem ...)
Eu diria que vá com o JMockit . É o mais fácil de usar, flexível e funciona em praticamente todos os casos, inclusive nos mais difíceis e nos cenários em que você não pode controlar a classe a ser testada (ou não pode quebrá-la devido a motivos de compatibilidade etc.).
Minhas experiências com o JMockit foram muito positivas.