Qual é a melhor estrutura simulada para Java? [fechadas]

347

Qual é a melhor estrutura para criar objetos simulados em Java? Por quê? Quais são os prós e os contras de cada estrutura?

Josh Brown
fonte

Respostas:

315

Eu tive um bom sucesso usando o Mockito .

Quando tentei aprender sobre o JMock e o EasyMock, achei a curva de aprendizado um pouco íngreme (embora talvez seja apenas eu).

Eu gosto do Mockito por causa de sua sintaxe simples e limpa que eu pude entender rapidamente. A sintaxe mínima foi projetada para suportar muito bem os casos comuns, embora nas poucas vezes em que precisei fazer algo mais complicado, achei que o que queria era suportado e fácil de entender.

Aqui está um exemplo (resumido) da página inicial do Mockito:

import static org.mockito.Mockito.*;

List mockedList = mock(List.class);
mockedList.clear();
verify(mockedList).clear();

Não fica muito mais simples que isso.

A única grande desvantagem em que consigo pensar é que ele não zombará de métodos estáticos.

Brian Laframboise
fonte
15
Bonita. Para métodos estáticos, basta combinar o Mockito com o JMockit e praticamente não há nenhuma classe "legada" para você poder testar.
Epaga 13/03/09
6
Eu amo como quando você tenta fazer algo que não deveria (por exemplo, criar zombarias inline), obtém uma explicação muito clara do que fez de errado na mensagem de exceção.
ripper234
3
Para mim, absolutamente. Eu ainda recomendaria incondicionalmente. Obviamente, se você encontrar outra estrutura que melhor atenda às suas necessidades, mencione-a em outra resposta e veja quais votos ela recebe e que tipo de comentários recebe.
precisa
2
@MexicanHacker, por que você não pode usá-lo no Android? Estou usando agora, com Robolectric.
Ilkka
2
Estou usando Mockito e adorando !! Ótima documentação também (tão raro encontrar documentação dessa qualidade, bom trabalho dos autores), o que é muito importante para usarmos coisas sem precisar cavar o código da estrutura !!!
Renato
84

Eu sou o criador do PowerMock, então, obviamente, devo recomendar isso! :-)

O PowerMock estende o EasyMock e o Mockito com a capacidade de zombar de métodos estáticos , finais e até particulares. O suporte ao EasyMock está completo, mas o plug-in Mockito precisa de mais trabalho. Também estamos planejando adicionar suporte ao JMock.

O PowerMock não se destina a substituir outras estruturas, mas pode ser usado em situações complicadas em que outras estruturas não permitem zombarias. O PowerMock também contém outros recursos úteis, como suprimir inicializadores e construtores estáticos .

Jan Kronquist
fonte
PowerMock é essencial para a unidade de teste de aplicações Android usando Java nativa no PC host (evitando usar o emulador lento)
Jeff Axelrod
Única questão @Jan é PowerMock é incompatível ao usar Robolectric embora :-( eu quero fazer @RunWith (PowerMockRunner.class) E @RunWith (RobolectricTestRunner.class)
Blundell
Depois de usar o PowerMock nos últimos meses, recomendo vivamente!
Cwash
O PowerMock é realmente incrível. Eu realmente amo singletons estáticos para acessar tudo, e isso possibilita o teste.
Ian Macalinao
Advertência: algumas coisas como zombar dos métodos finais só são possíveis no Powermock para EasyMock e não no Mockito. É um pouco complicado quando você não o usa com tanta frequência. Fiquei me perguntando por que algo não estava funcionando, então percebi que ele só estava listado na seção Easymock do documento.
Trafalmadorian
46

O site do projeto JMockit contém muitas informações comparativas para os kits de ferramentas de simulação atuais.

Em particular, confira a matriz de comparação de recursos , que abrange EasyMock, jMock, Mockito, Unitils Mock, PowerMock e, é claro, JMockit. Tento mantê-lo preciso e atualizado, o máximo possível.

Rogério
fonte
11
Estou impressionado com o JMockit, ele tem uma curva de aprendizado mais acentuada, mas tem uma documentação muito boa há anos e pode zombar de qualquer coisa. Comecei com o Mockito, que era fácil de aprender, mas encontrava regularmente problemas que não conseguia resolver com ele. Por outro lado, nem consigo imaginar o que é impossível com o JMockit.
Hontvári Levente 16/04/2015
21

Eu tenho tido sucesso com o JMockit .

É bem novo e, portanto, um pouco cru e sub-documentado. Ele usa o ASM para redefinir dinamicamente o bytecode da classe, para que possa zombar de todos os métodos, incluindo estático, privado, construtores e inicializadores estáticos. Por exemplo:

import mockit.Mockit;

...
Mockit.redefineMethods(MyClassWithStaticInit.class,
                       MyReplacementClass.class);
...
class MyReplacementClass {
  public void $init() {...} // replace default constructor
  public static void $clinit{...} // replace static initializer
  public static void myStatic{...} // replace static method
  // etc...
}

Possui uma interface de expectativas, permitindo também cenários de gravação / reprodução:

import mockit.Expectations;
import org.testng.annotations.Test;

public class ExpecationsTest {
  private MyClass obj;

  @Test
  public void testFoo() {
    new Expectations(true) {
      MyClass c;
      {
        obj = c;
        invokeReturning(c.getFoo("foo", false), "bas");
      }
    };

    assert "bas".equals(obj.getFoo("foo", false));

    Expectations.assertSatisfied();
  }

  public static class MyClass {
    public String getFoo(String str, boolean bool) {
      if (bool) {
        return "foo";
      } else {
        return "bar";
      }
    }
  }
}

A desvantagem é que ele requer Java 5/6.

Kris Pruden
fonte
sim, pode realmente recomendar isso
Epaga 22/10/08
7
Apenas uma atualização: o projeto JMockit foi movido para code.google.com/p/jmockit . Ele evoluiu MUITO desde esse post (e ainda está evoluindo) e agora possui uma extensa documentação.
Rogério
JMockit mudou novamente. Agora está disponível no Github. jmockit.github.io
Ravi Thapliyal
15

Você também pode dar uma olhada nos testes usando o Groovy. No Groovy, você pode facilmente zombar de interfaces Java usando o operador 'as':

def request = [isUserInRole: { roleName -> roleName == "testRole"}] as HttpServletRequest 

Além dessa funcionalidade básica, o Groovy oferece muito mais na frente de zombaria, incluindo os poderosos MockFore as StubForclasses.

http://docs.codehaus.org/display/GROOVY/Groovy+Mocks

p3t0r
fonte
13

Comecei a usar zombarias com o EasyMock . Fácil de entender, mas a etapa de repetição foi meio irritante. O Mockito remove isso, também possui uma sintaxe mais limpa, pois parece que a legibilidade era um dos seus principais objetivos. Não posso enfatizar o suficiente o quanto isso é importante, já que a maioria dos desenvolvedores gasta seu tempo lendo e mantendo o código existente, não o criando.

Outra coisa interessante é que interfaces e classes de implementação são tratadas da mesma maneira, ao contrário do EasyMock, onde você ainda precisa se lembrar (e verificar) para usar uma Extensão de Classe EasyMock.

Dei uma olhada rápida no JMockit recentemente e, embora a lista de recursos seja bastante abrangente, acho que o preço disso é legibilidade do código resultante e é preciso escrever mais.

Para mim, Mockito atinge o ponto ideal, sendo fácil de escrever e ler, e lidando com a maioria das situações que a maioria dos códigos exige. Usar o Mockito com o PowerMock seria minha escolha.

Uma coisa a considerar é que a ferramenta que você escolheria se estivesse desenvolvendo sozinha ou em uma pequena equipe unida pode não ser a melhor opção para uma grande empresa com desenvolvedores de diferentes níveis de habilidade. Legibilidade, facilidade de uso e simplicidade precisariam de mais consideração neste último caso. Não faz sentido obter a estrutura de zombaria definitiva se muitas pessoas acabam não a usando ou não mantendo os testes.

trafalmadorian
fonte
11
+1 Esta resposta precisa de mais votos. Deve-se compartilhar o que eles realmente gostaram ou não sobre a estrutura. Apenas "usei isso ... e gostei!" é uma das razões pelas quais essas boas perguntas são encerradas no SO.
Ravi Thapliyal
11

Estamos usando muito o EasyMock e o EasyMock Class Extension no trabalho e estamos muito felizes com isso. Basicamente, fornece tudo o que você precisa. Dê uma olhada na documentação, há um exemplo muito bom que mostra todos os recursos do EasyMock.

dlinsin
fonte
11
Na minha pergunta, eu estava mais procurando o que você gosta e o que não gosta em uma estrutura simulada. Posso encontrar a documentação e ler tudo sobre ela - quero saber o que as pessoas que a usaram pensam dela.
Josh Brown
O EasyMock funciona apenas no Java 5 e superior, argh!
matt b
8

Eu usei o JMock cedo. Eu tentei o Mockito no meu último projeto e gostei. Mais conciso, mais limpo. O PowerMock cobre todas as necessidades ausentes no Mockito, como zombar de um código estático, zombar de uma criação de instância, zombar de classes e métodos finais. Então, eu tenho tudo o que preciso para realizar meu trabalho.

Dmitry
fonte
6

Eu gosto do JMock porque você é capaz de estabelecer expectativas. Isso é totalmente diferente de verificar se um método foi chamado encontrado em algumas bibliotecas simuladas. Usando o JMock, você pode escrever expectativas muito sofisticadas. Veja o jmock cheat- sheat .

Andrea Francia
fonte
5

Sim, o Mockito é uma ótima estrutura. Eu o uso junto com o hamcrest e o Google guice para configurar meus testes.

Bartosz Bierkowski
fonte
4

A melhor solução para zombar é fazer com que a máquina faça todo o trabalho com testes automatizados baseados em especificações. Para Java, consulte ScalaCheck e a estrutura Reductio incluída na biblioteca Java Funcional . Com estruturas de teste automatizadas baseadas em especificação, você fornece uma especificação do método em teste (uma propriedade sobre isso que deve ser verdadeira) e a estrutura gera testes e objetos simulados automaticamente.

Por exemplo, a propriedade a seguir testa o método Math.sqrt para verificar se a raiz quadrada de qualquer número positivo n ao quadrado é igual a n.

val propSqrt = forAll { (n: Int) => (n >= 0) ==> scala.Math.sqrt(n*n) == n }

Quando você liga propSqrt.check(), o ScalaCheck gera centenas de números inteiros e verifica sua propriedade para cada um, também assegurando automaticamente que os casos extremos sejam bem cobertos.

Embora o ScalaCheck seja escrito em Scala e exija o Scala Compiler, é fácil testar o código Java com ele. A estrutura Reductio em Java Funcional é uma implementação Java pura dos mesmos conceitos.

Apocalisp
fonte
3

O Mockito também oferece a opção de métodos de stubbing, correspondência de argumentos (como anyInt () e anyString ()), verificação do número de invocações (times (3), atLeastOnce (), never ()) e muito mais .

Também descobri que o Mockito é simples e limpo .

Uma coisa que eu não gosto no Mockito é que você não pode stub métodos estáticos .

Josh Brown
fonte
Esta resposta é imprecisa. Você não está limitado a interfaces com o jMock. Você pode simular classes concretas com o ClassImposteriser.
Teflon Ted
Você pode fazer exatamente as mesmas coisas com o EasyMock também.
Cem Catikkas 14/09/08
Eu removi as imprecisões da minha resposta.
21910 Josh Brown
2

Para algo um pouco diferente, você pode usar o JRuby e o Mocha, que são combinados no JtestR para escrever testes para o seu código Java no Ruby expressivo e sucinto. Existem alguns exemplos úteis de zombaria com o JtestR aqui . Uma vantagem dessa abordagem é que zombar de classes concretas é muito direto.

James Mead
fonte
1

Comecei a usar zombarias através do JMock, mas eventualmente fiz a transição para usar o EasyMock. O EasyMock era exatamente isso - mais fácil - e fornecia uma sintaxe que parecia mais natural. Eu não mudei desde então.

Mike Furtak
fonte