De acordo com o post Passagem de parâmetros para método mockado, a quantidade de parâmetros passados para o método mockado deve ser igual a do método "de verdade", desta forma encontrei um problema esta manhã:
Tinha um teste para um método, e nele, mockava um método de um outro objeto da seguinte forma:
historicoClienteDao.expects(once()).method("findByFiltros").with(1L, "nome", null, 3L).will(returnValue(historicos));
porém, este método ganhou mais um parâmetro e quando o adicionei, deu erro de compilação:
historicoClienteDao.expects(once()).method("findByFiltros").with(1L, "nome", null, 3L, true).will(returnValue(historicos));
pois o método with só recebe 4 Constraints.
Aí foi que percebi que ele também recebe um array de Constraints e então o "problema" foi resolvido da seguinte forma:
historicoClienteDao.expects(once()).method("findByFiltros").with(new Constraint[]{1L, "nome", null, 3L, true}).will(returnValue(historicos));
ps. a ferramenta usada neste exemplo é o JMock.
Mostrando postagens com marcador JMock. Mostrar todas as postagens
Mostrando postagens com marcador JMock. Mostrar todas as postagens
quarta-feira, 16 de janeiro de 2008
quinta-feira, 6 de dezembro de 2007
JMock versus Classes Concretas 2 - A Missão
Me recuperando da decepção da incompatibilidade de versões do JMock, ví que o JMock 1 pode mockar classes concretas.
Baixei o jmock-cglib-version.jar, e fiz como diz no link abaixo:
http://www.jmock.org/jmock1-cglib.html
e funcionou.
A única limitação é que não pode ser uma classe final.
JMock acaba de recuperar seus pontos.
Thanks, Nat Pryce.
Baixei o jmock-cglib-version.jar, e fiz como diz no link abaixo:
http://www.jmock.org/jmock1-cglib.html
e funcionou.
A única limitação é que não pode ser uma classe final.
JMock acaba de recuperar seus pontos.
Thanks, Nat Pryce.
quarta-feira, 5 de dezembro de 2007
JMock versus Classes Concretas
O JMock (acho que o EasyMock também) precisa de uma interface para ser instanciado, mas eu precisei usar com uma Classe Concreta.
Sei que a primeira idéia é: "Porque você não cria uma interface?"
No meu caso, até poderia, mas imagine um sistema legado, onde você esteja mantendo, criar uma interface e alterar um monte de classes talvez não seja o ideal.
E isso me motivou a procurar uma solução para este problema, no site do JMock, encontrei uma referencia ao CGLib (links abaixo):
http://www.jmock.org/jmock1-cglib.html
http://www.jmock.org/mocking-classes.html
algumas horas depois...
Nas soluções acima, me parece que só funciona com o JMock 2, e aí vem a notícia mais triste que tive desde que comecei a fazer testes:
Os testes feitos com JMock 1 não rodam se eu mudar o jar do JMock para a versão 2.
Indo no site (http://www.jmock.org/versioning.html) vi isso:
2.0.0 Incompatible API changes, removes API elements deprecated by version 1.2.0.
Bem, pra quem usa JMock 1 e não quer re-fazer TODOS os seus testes, crie uma interface para a classe que será mockada.
O JMock acaba de perder 5 pontos.
Sei que a primeira idéia é: "Porque você não cria uma interface?"
No meu caso, até poderia, mas imagine um sistema legado, onde você esteja mantendo, criar uma interface e alterar um monte de classes talvez não seja o ideal.
E isso me motivou a procurar uma solução para este problema, no site do JMock, encontrei uma referencia ao CGLib (links abaixo):
http://www.jmock.org/jmock1-cglib.html
http://www.jmock.org/mocking-classes.html
algumas horas depois...
Nas soluções acima, me parece que só funciona com o JMock 2, e aí vem a notícia mais triste que tive desde que comecei a fazer testes:
Os testes feitos com JMock 1 não rodam se eu mudar o jar do JMock para a versão 2.
Indo no site (http://www.jmock.org/versioning.html) vi isso:
2.0.0 Incompatible API changes, removes API elements deprecated by version 1.2.0.
Bem, pra quem usa JMock 1 e não quer re-fazer TODOS os seus testes, crie uma interface para a classe que será mockada.
O JMock acaba de perder 5 pontos.
terça-feira, 4 de dezembro de 2007
Passagem de parâmetros para método mockado
Bem,
quando você mocka uma classe, você deve informar, no método de teste, o que o método deve fazer, então, vejamos:
classeDao.expects(once()).method("getAlgumaCoisa").
with(eq(1), eq(true)).will(returnValue(obj));
Traduzindo:
A classeDao é um mock, e neste escopo (método de teste), ele será invocado 1 única vez (expects(once())), o método que será chamado é o getAlgumaCoisa (method("getAlgumaCoisa")), quando passar os parâmetros 1 e true (with(eq(1), eq(true))), retorne um Object obj (will(returnValue(obj))).
Simples, porém me deparei com uma situação bem estranha:
O método que eu estava testando, passava como parâmetro a data atual, e não o recebia como parâmetro. Bem, o problema é o fato do método instanciar um objeto e passar como parâmetro para outro método (que iremos mockar).
Vou simplificar com um exemplo:
Na classe classeManager
o metodo fazAlgo():
//faz um blablabla
classeDao.getAlgumaCoisa(new String[]{"1", "2"});
//faz o resto do blablabla
no meu test:
Estou testando a classe classeManager
o método testFazAlgo():
se eu fizer:
classeDao.expects(once()).method("getAlgumaCoisa").
with(eq(new String[]{"1", "2"})).will(returnValue(obj));
não vai funcionar, ele vai me dizer que o método nunca foi invocado.
Pra quem já estudou um pouco de O.O. já deve ter percebido, o objeto que instanciei na classe classeManager (classeDao.getAlgumaCoisa(new String[]{"1", "2"});) é diferente do instanciado na classe de testes (classeDao.expects(once()).method("getAlgumaCoisa").
with(eq(new String[]{"1", "2"})).will(returnValue(obj));).
Então a solução é:
classeDao.expects(once()).method("getAlgumaCoisa").
with(ANYTHING).will(returnValue(obj));
o que quer dizer:
Quando eu passar "Qualquer Coisa" (with(ANYTHING)) para o método getAlgumaCoisa, retorne o obj.
Importante lembrar que a quantidade de parâmetros deve ser igual a do método "de verdade".
quando você mocka uma classe, você deve informar, no método de teste, o que o método deve fazer, então, vejamos:
classeDao.expects(once()).method("getAlgumaCoisa").
with(eq(1), eq(true)).will(returnValue(obj));
Traduzindo:
A classeDao é um mock, e neste escopo (método de teste), ele será invocado 1 única vez (expects(once())), o método que será chamado é o getAlgumaCoisa (method("getAlgumaCoisa")), quando passar os parâmetros 1 e true (with(eq(1), eq(true))), retorne um Object obj (will(returnValue(obj))).
Simples, porém me deparei com uma situação bem estranha:
O método que eu estava testando, passava como parâmetro a data atual, e não o recebia como parâmetro. Bem, o problema é o fato do método instanciar um objeto e passar como parâmetro para outro método (que iremos mockar).
Vou simplificar com um exemplo:
Na classe classeManager
o metodo fazAlgo():
//faz um blablabla
classeDao.getAlgumaCoisa(new String[]{"1", "2"});
//faz o resto do blablabla
no meu test:
Estou testando a classe classeManager
o método testFazAlgo():
se eu fizer:
classeDao.expects(once()).method("getAlgumaCoisa").
with(eq(new String[]{"1", "2"})).will(returnValue(obj));
não vai funcionar, ele vai me dizer que o método nunca foi invocado.
Pra quem já estudou um pouco de O.O. já deve ter percebido, o objeto que instanciei na classe classeManager (classeDao.getAlgumaCoisa(new String[]{"1", "2"});) é diferente do instanciado na classe de testes (classeDao.expects(once()).method("getAlgumaCoisa").
with(eq(new String[]{"1", "2"})).will(returnValue(obj));).
Então a solução é:
classeDao.expects(once()).method("getAlgumaCoisa").
with(ANYTHING).will(returnValue(obj));
o que quer dizer:
Quando eu passar "Qualquer Coisa" (with(ANYTHING)) para o método getAlgumaCoisa, retorne o obj.
Importante lembrar que a quantidade de parâmetros deve ser igual a do método "de verdade".
segunda-feira, 3 de dezembro de 2007
Quero usar mocks, uso JMock ou EasyMock?
Bem, já vi defensores das duas "ferramentas", eu prefiro o JMock, acho ele muito simples e bem funcional, de qualquer forma, vou colocar aqui os links para download dos dois:
JMock: http://www.jmock.org/
EasyMock: http://www.easymock.org/
Se você quer começar com JMock: http://www.jmock.org/getting-started.html
Pra ver um caso simples das duas formas, isso pode ajudar a escolher: http://blogs.warwick.ac.uk/colinyates/entry/jmock_versus_easymock/
Aqui tem uma tabelinha com algumas diferenças: http://www.tcay.com/dev/JMockVsEasyMock.htm
JMock: http://www.jmock.org/
EasyMock: http://www.easymock.org/
Se você quer começar com JMock: http://www.jmock.org/getting-started.html
Pra ver um caso simples das duas formas, isso pode ajudar a escolher: http://blogs.warwick.ac.uk/colinyates/entry/jmock_versus_easymock/
Aqui tem uma tabelinha com algumas diferenças: http://www.tcay.com/dev/JMockVsEasyMock.htm
Assinar:
Postagens (Atom)