Um dos frameworks que mais gosto de trabalhar, devido a sua simplicidade e produtividade é o Vraptor. Uma das suas vantagens é que ele abstrai a complexidade da API de Servlets, NÃO te obriga a trabalhar com getters/setters evitando que seu modelo se torne anêmico. Não é intrusivo, você foca na sua lógica de negócios e não em aprender sobre a arquitetura e classes do framework, ou seja, a curva de aprendizado é minima.
Trabalha de forma muito fácil com injeção de dependência. Não é necessário configurar quase nada. Tem suporte a REST e inumeros outros recursos. Mas oque chama realmente a atenção é que você consegue começar a trabalhar com ele em questão de minutos. Poderiamos ficar o dia todo discutindo sobre as vantagens de utilizar este framework. Portanto vamos ao objetivo do post: Aprender a testar unitáriamente as classes de controller do Vraptor.
Para isso utilizaremos o JUnit e o Mockito.
Desejamos testar o método salva(Aluno aluno) do controller abaixo. Este método recebe um aluno, verifica se é valido, salva e redireciona para a listagem, caso o aluno seja inconsistente ele redireciona para a página de cadastro/edição para exibir os erros.
@Resource public class AlunoController { private AlunoRepository alunoRepository; private Result result; private Validator validator; public AlunoController(AlunoRepository alunoRepository, Result result, Validator validator) { this.alunoRepository = alunoRepository; this.result = result; this.validator = validator; } public void add(Aluno aluno) { this.validator.validate(aluno); this.validator.onErrorForwardTo(this).cadastra(); this.alunoRepository.add(aluno); this.result.redirectTo(this).lista(); } }Temos como dependência a interface AlunoRepository e como o objetivo é testar o controller, devemos mockar esta dependência.
Criamos uma classe de teste comum do JUnit.
public class AlunoControllerTest { private AlunoController controller; private AlunoRepository alunoRepository; private MockResult result; private JSR303MockValidator validator; @Before public void setUp() throws Exception { this.alunoRepository = mock(AlunoRepository.class); result = spy(new MockResult()); validator = spy(new JSR303MockValidator()); controller = new AlunoController(alunoRepository, turmaRepository, result, validator); } }
Note que os objetos result e validator usam mocks apropriados, portanto não precisamos nos preocupar com eles. É melhor utilizar estes mocks fornecidos, pois estes objetos usam Fluent Interface oque torna sua testabilidade muito difícil.
Repare também que usamos o método spy(T object) para obter as instancias do result e validator, isso é util pois conseguimos chamar os métodos reais dos objetos, então podemos verificar se realmente houveram interações com os objetos.
O teste:
@Test public void add() { Aluno aluno = getAlunoConsistente(); controller.add(aluno); verify(alunoRepository).add(aluno); }Através deste teste tentamos salvar um aluno, que é um objeto consistente (válido). Então o aluno deve ser adicionado ao repositório, portanto nos asseguramos que o método add(Aluno aluno) do repositório foi chamado, isso é feito através da linha: verify(alunoRepository).add(aluno);
Para testarmos nossas validações, desenvolvemos um teste que espera que uma ValidationException seja lançada e nos asseguramos que não houveram interações com o repositório:
@Test(expected = ValidationException.class) public void gravaAlunoInconsistenteTest() { controller.grava(getAlunoInconsistente()); verifyNoMoreInteractions(alunoRepository); }Esse post teve origem em uma thread do GUJ que abri e recebi orientações do Lucas Cavalcanti: http://www.guj.com.br/java/243436-vraptor-e-mockito---testes-de-controllers
UPDATE:
Muitas vezes desejamos verificar se o nosso método fez um redirecionamento para uma view ou lógica específica. Então como o Lucas citou, podemos fazer:
AlunoController spy = Mockito.spy(alunoController); when(result.redirectTo(alunoController)).thenReturn(spy); this.alunoController.grava(aluno); verify(spy).lista();
Assim estamos nos assegurando que o método lista() foi chamado, ou seja, foi feito o redirecionamento.
Abraços