Coding Dojo Floripa

Desenvolvimento Ágil

Mocks vs Stubs: qual a diferença afinal?

Publicado por Ivan Sanchez em Sexta-feira, Outubro 20, 2006

Mock Objects representam uma abordagem para simular objetos dentro dos testes. Isso nos ajuda quando o objeto real é muito complexo, lento ou ainda nem existe. Até este ponto mocks são bem parecidos com stubs. A diferença entre eles está nas abordagens que eles propõem:

  • Com stubs, nos preocupamos em testar o estado dos objetos após a execução do método. Neste caso incluimos os asserts para ver se o método nos levou ao estado que esperamos.
  • Com mocks, a preocupação é testar a interação entre objetos durante a execução do método. Neste caso, os asserts servem para ver se os métodos se relacionaram como o esperado.

Exemplo: usando Mocks para testar Servlets

Se usássemos mocks ao invés de stubs no nosso exemplo de stubs, teríamos algo como:

import static org.easymock.EasyMock.*;

public class ServletHelloWorldTest extends TestCase

{

    public void testService() throws ServletException, IOException

    {

        ServletHelloWorld servlet = new ServletHelloWorld();

        HttpServletRequest request = createMock(HttpServletRequest.class);

        HttpServletResponse response = createMock(HttpServletResponse.class);

        HttpSession session = createMock(HttpSession.class);

        expect(request.getParameter("nome")).andReturn(null);

        expect(request.getSession()).andReturn(session);

        replay(request);

        session.setAttribute("mensagem", "Hello World");

        replay(session);

        servlet.service(request, response);

        verify(request);

        verify(session);

    }

    public void testServiceComParametro() throws ServletException, IOException

    {

        ServletHelloWorld servlet = new ServletHelloWorld();

        HttpServletRequest request = createMock(HttpServletRequest.class);

        HttpServletResponse response = createMock(HttpServletResponse.class);

        HttpSession session = createMock(HttpSession.class);

        expect(request.getParameter("nome")).andReturn("João");

        expect(request.getSession()).andReturn(session);

        replay(request);

        session.setAttribute("mensagem", "Hello João");

        replay(session);

        servlet.service(request, response);

        verify(request);

        verify(session);

    }

}

Neste exemplo usamos o framework EasyMock que permite gerar os objetos mocks dentro dos testes, sem necessidade de implementar classes adicionais. Percebam que no teste, seguimos os seguintes passos:

  1. Criamos os mocks todos da mesma maneira, utilizando o comando createMock().
  2. Após a sua criação,utilizamos o método expect() para definir o comportamento que os métodos do mock terão ao serem invocados.
  3. Depois, usamos o replay() para indicar que os mocks estão prontos para uso e,
  4. Finalmente deixamos que o próprio framework verifique se a interação entre o objeto testado e o mock ocorreu como o esperado, através do método verify().

Desta forma conseguimos testar com a mesma eficiência dos stubs, mas com a vantagem de não precisarmos implementar nenhuma classe extra. Este também é o motivo que normalmente utilizamos stubs apenas quando estes são necessários, enquanto os mocks podem ser utilizados largamente nos testes quando queremos aumentar o isolamento entre as classes que estão sendo testadas.

Deixar uma Resposta

XHTML: Pode utilizar estas tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>