Exercício Mock-Reflexao

2
  Mock objects são uma técnica usada para se testar sistemas orientados a objetos. A idéia é substituir um objeto complexo por uma versão "falsa" dele ( mock  quer dizer "maquete") que tem um comportamento simples e facilmente previsível - por exemplo, retornando constantes em todos os métodos. Suponha que tenhamos o seguinte método na classe Receita: // Carrega os dados da receita de um servidor void loadFromServer(Server s) { s.open(); while (! s.endOfMessage()) { Ingrediente i = new Ingrediente(s.getString(), s.getInteger()); adicionaIngrediente(i); } } Presume-se que a classe Server  seja uma classe complexa que depende de inúmeros fatores, como uma rede devidamente configurada, acessos remotos, etc. Para testarmos o método loadFromServer  sem  precisarmos nos preocupar com esses detalhes que são externos ao método, substituímos a classe Server  por uma classe mock: class ServerMock { private static int contador = 1; public void open() { }; public boolean endOfMessage() { //A mensagem só acaba quando contador for igual a 3 if (contador++ == 3) { return true; } else { return false; } } public String getString() { return "TESTE"; } public int getInteger() { return 1; } } A parte chata de se usar mock objects é que pra fazer os testes, precisamos trocar todos os lugares no  programa onde a classe é usada pela classe mock equivalente. Ou seja, no método loadFromServer teríamos de declarar o parâmetro como "ServerMock" ao invés de "Server". Com aspectos, no entanto, podemos fazer essa substituição automaticamente, com algumas vantagens adicionais. O objetivo desse trabalho é desenvolver um aspecto para auxiliar os desenvolvedores no uso de mock objects. O aspecto deve se comportar da seguinte forma:  Ao fazer qualquer chamada de método, o sistema deve verificar se existe um método mock equivalente. Métodos mock terão a mesma assinatura que o método verdadeiro e estarão em uma classe que tem o mesmo nome da classe verdadeira, com a extensão "Mock" (como no exemplo acima, "Server" e "ServerMock").  Se o método mock existir, ele deve ser executado no lugar do método verdadeiro.  Se o método mock não existir ou não puder ser executado por algum motivo, deve-se executar o método verdadeiro. Dicas:  Você vai precisar de reflexão para resolver esse problema. Use as seguintes declarações para importar as bibliotecas de reflexão:

Transcript of Exercício Mock-Reflexao

  • Mock objects so uma tcnica usada para se testar sistemas orientados a objetos. A idia substituir um objeto complexo por uma verso "falsa" dele (mock quer dizer "maquete") que tem um comportamento simples e facilmente previsvel - por exemplo, retornando constantes em todos os mtodos. Suponha que tenhamos o seguinte mtodo na classe Receita: // Carrega os dados da receita de um servidor void loadFromServer(Server s) { s.open(); while (! s.endOfMessage()) { Ingrediente i = new Ingrediente(s.getString(), s.getInteger()); adicionaIngrediente(i); } } Presume-se que a classe Server seja uma classe complexa que depende de inmeros fatores, como uma rede devidamente configurada, acessos remotos, etc. Para testarmos o mtodo loadFromServer sem precisarmos nos preocupar com esses detalhes que so externos ao mtodo, substitumos a classe Server por uma classe mock: class ServerMock { private static int contador = 1; public void open() { }; public boolean endOfMessage() { //A mensagem s acaba quando contador for igual a 3 if (contador++ == 3) { return true; } else { return false; } } public String getString() { return "TESTE"; } public int getInteger() { return 1; } }

    A parte chata de se usar mock objects que pra fazer os testes, precisamos trocar todos os lugares no programa onde a classe usada pela classe mock equivalente. Ou seja, no mtodo loadFromServer teramos de declarar o parmetro como "ServerMock" ao invs de "Server".

    Com aspectos, no entanto, podemos fazer essa substituio automaticamente, com algumas vantagens adicionais. O objetivo desse trabalho desenvolver um aspecto para auxiliar os desenvolvedores no uso de mock objects. O aspecto deve se comportar da seguinte forma:

    Ao fazer qualquer chamada de mtodo, o sistema deve verificar se existe um mtodo mock equivalente. Mtodos mock tero a mesma assinatura que o mtodo verdadeiro e estaro em uma classe que tem o mesmo nome da classe verdadeira, com a extenso "Mock" (como no exemplo acima, "Server" e "ServerMock").

    Se o mtodo mock existir, ele deve ser executado no lugar do mtodo verdadeiro. Se o mtodo mock no existir ou no puder ser executado por algum motivo, deve-se executar o

    mtodo verdadeiro.

    Dicas:

    Voc vai precisar de reflexo para resolver esse problema. Use as seguintes declaraes para importar as bibliotecas de reflexo:

  • import org.aspectj.lang.reflect.*; import java.lang.reflect.*;

    A classe CodeSignature uma subclasse de Signature (ver a aula) que define o mtodo "Class[] getParameterTypes()", que retorna um vetor com as classes dos tipos dos parmetros do mtodo. Esse vetor serve como argumento para o mtodo getMethod(nome, tipos_dos_parametros) da classe Class.

    Existe uma soluo para esse problema com um pointcut e um advice, com 10 linhas de cdigo no corpo do advice. Outras solues tambm sero aceitas.

    Deve-se entregar o aspecto e um programa que demonstre que o aspecto funciona.