[Tiago Peczenyj] JMock - trabalhando com mock objets em java

Lendo sobre testes unitarios, imagine o caso onde o seu teste é complexo: um objeto que chama outro e, então, realiza as suas tarefas. Um bom caso é um DAO que acessa o banco de dados para fazer alguma coisa: se vc pensa em testar esse codigo de forma unitaria teria que subir um banco de testes e, se encontrasse um problema, poderia ser dificil dizer se é problema do DAO ou dos objetos que ele depende (como a conexão com o banco, ou o banco em si).

A solução para estes casos pode ser trabalhar com mocks: objetos “burros” que podem não ter nenhuma função alem de responder ao que vc especificou. A abordagem mais utilizada é vc programar estes objetos para responder a um ou mais metodos com argumentos especificos, assim como as respostas esperadas. No caso do DAO eu posso esperar um determinado SQL e especificar uma determinada resposta, tudo de acordo com o meu cenario de teste.

É claro que Mock Objects em excesso podem atrapalhar, mas é tudo uma questão de bom senso: costumo dizer para quem esta começando a focar os testes nas partes mais importantes do sistema, o core do modelo e regras de negocio e, então, incrementar estas praticas caso veja necessidade. Sem falar que volta e meia surge algo novo.

Para java existe o excelente framework JMock. Logo de cara o site oficial traz um exemplo de como utilizar um mock bem simples (incluindo a integração do mesmo com JUnit 4)

http://www.jmock.org/getting-started.html

Para entender, imagine esta interface

interface Subscriber {
void receive(String message);
}

Imagine que eu tenho um objeto do tipo Publisher que, ao invocar o metodo publish(message), ele envie esta mensagem para um Subscriber (que recebe com o metodo acima). Para testar o publish eu teria que me certificar que o metodo receive deste objeto Subscriber foi invocado com a mensagem especificada, mais ou menos assim:

import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.jmock.Expectations;

@RunWith(JMock.class)
class PublisherTest {
Mockery context = new JUnit4Mockery();

@Test
public void oneSubscriberReceivesAMessage() {
// set up
final Subscriber subscriber = context.mock(Subscriber.class);

Publisher publisher = new Publisher(); // objeto que vou testar
publisher.add(subscriber); // tenho que adicionar o mock!

final String message = “message”;

// aqui eu programo o que eu espero do teste
context.checking(new Expectations() {{
oneOf (subscriber).receive(message);
}});

// aqui eu executo!
publisher.publish(message);
}
}

Facil?