Vraptor e mockito - testes de controllers

Pessoal,

estou tentando assegurar no teste que o método redirecione para outro metodo ou view especifica, porém não estou obtendo 100% de êxito, estou fazendo com mockito, segue a situação na prática:

CONTROLLER

public void grava(Aluno aluno) {
   this.validator.validate(aluno);
   validator.onErrorForwardTo(this).cadastra();
   if(condicao qualquer) {
      this.result.redirectTo(this).lista();
   } else {
      this.result.redirectTo(this).outroMetodo();
   }
}

TESTE

@Test
public void gravaTest() {
  Aluno aluno = new Aluno();
  aluno.setNome("Jose");
  this.controller.grava(aluno);
  verify(this.result).redirectTo(this.controller);
}

meu result é um spy(new MockResult());

meu teste passa pois o metodo redirectTO é chamado…

porém quero verificar se o método lista() do controller foi chamado, então faço:

@Test
public void gravaTest() {
  Aluno aluno = new Aluno();
  aluno.setNome("Jose");
  this.controller.grava(aluno);
  doReturn(this.controller).when(this.result).redirectTo(this.controller);
  verify(this.result).redirectTo(this.controller).lista();
}

mesmo colocando a linha doReturn… quando chamo verify(this.result).redirectTo(this.controller) é retornado null… logo recebo um nullPointerEx

alguem sabe como verificar se o método lista() está realmente sendo chamado ?

abrassss

o doReturn deveria ficar antes do método que vai interagir com o result…

@Test  
public void gravaTest() {  
  Aluno aluno = new Aluno();  
  aluno.setNome("Jose");  
  doReturn(this.controller).when(this.result).redirectTo(this.controller);
  this.controller.grava(aluno);  
  verify(this.result).redirectTo(this.controller).lista();  
}  

o mockito só verifica a primeira interação, não dá pra fazer a linha:

 verify(this.result).redirectTo(this.controller).lista(); 

o que vc pode fazer é modificar o seu doReturn para retornar um spy:

SeuController spy = Mockito.spy(controller);
when(result.redirectTo(controller)).thenReturn(spy);

this.controller.grava(aluno);

verify(spy).lista();

não precisa nem fazer o verify no redirect, pois só vai executar o lista() se passar por ele.

Lucas Cavalcanti excelente! obrigado pela prontidão na resposta!

o vraptor realmente é um excelente framework…
fácil de testar, fácil de desenvolver…

vou blogar como testar os controllers e fazer referência a esse post…

parabéns pelo ótimo trabalho…

abrassss

outra questao eh:

CONTROLLER

this.validator.validate(aluno);
validator.onErrorForwardTo(this).cadastra();
this.result.redirectTo(this).lista();

se meu objeto aluno não passa na validação, o método lista não deveria ser chamado, porém devido ao uso do ValidatorMock o forward nao acontece, logo lista é chamado indevidamente.

existe alguma forma de contornar a situaçao ?

abrasss

o mockValidator não executa a validação de verdade…

o que vc pode fazer é usar o JSR303MockValidator (caso esteja usando BeanValidation) ou o HibernateMockValidator (caso esteja usando HV 3)

caso essas classes ainda não estejam disponíveis, vc pode copiá-las:


https://github.com/caelum/vraptor/blob/master/vraptor-core/src/main/java/br/com/caelum/vraptor/util/test/HibernateMockValidator.java

Excelente!

funcionou lindo… controllers testados!

porém tive de usar o hibernate-validator 3x com o 4 da classnotfoundex…

abrasssss

classNotFound em qual classe?

prefira usar o Hibernate Validator 4, pois ele faz parte da especificação BeanValidations do java…

usando o valitator 4.1.0.Final

da:


java.lang.NoClassDefFoundError: org/hibernate/validator/ClassValidator
	at br.com.caelum.vraptor.validator.ValidatorLocator.getValidator(ValidatorLocator.java:47)
	at br.com.caelum.vraptor.validator.HibernateValidator3.validate(HibernateValidator3.java:47)
	at br.com.caelum.vraptor.util.test.HibernateMockValidator.validate(HibernateMockValidator.java:22)
	at br.com.yarabastos.controller.AlunoController.grava(AlunoController.java:38)
	at br.com.yarabastos.test.controller.AlunoControllerTest.gravaAlunoTest(AlunoControllerTest.java:65)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
	at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
	at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

abrassss

tente usar esses jars:

https://github.com/caelum/vraptor/blob/master/vraptor-core/lib/optional/hibernate/hibernate-validator-4.0.2.GA.jar

https://github.com/caelum/vraptor/blob/master/vraptor-core/lib/optional/hibernate/validation-api-1.0.0.GA.jar

e remover os outros jars do hibernate-validator… se ainda estiver dando erro tente dar um clean no projeto e no server, deveria funcionar

excelente, porem, como coloco essas dependencias no meu pom.xml ?

pergunta imbecil, esquece, ja achei no rep do maven… vou testar

obrigado lucas

abrasss

lucas, mesma ex…

<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>3.6.4.Final</version>
		</dependency>

		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-validator</artifactId>
			<version>4.0.2.GA</version>
		</dependency>

		<dependency>
			<groupId>javax.validation</groupId>
			<artifactId>validation-api</artifactId>
			<version>1.0.0.GA</version>
		</dependency>

sao esses os pacotes mesmo ?

edit:
pq dentro desses jars realmente n existe a classe ClassValidator

abrasss

roda:

mvn dependency:tree

e vê se aparece mais de um hibernate-validator…
se não se importar, posta aqui o resultado

apenas o novo mesmo


[INFO] [dependency:tree {execution: default-cli}]
[INFO] br.com.yarabastos:yarabastos:war:0.0.1-SNAPSHOT
[INFO] +- br.com.caelum:vraptor:jar:3.3.1:compile
[INFO] |  +- cglib:cglib-nodep:jar:2.1_3:compile
[INFO] |  +- com.google.guava:guava:jar:r07:compile
[INFO] |  +- org.slf4j:slf4j-api:jar:1.6.1:compile
[INFO] |  +- org.slf4j:slf4j-log4j12:jar:1.6.1:compile
[INFO] |  |  \- log4j:log4j:jar:1.2.16:compile
[INFO] |  +- net.vidageek:mirror:jar:1.5.1:compile
[INFO] |  +- org.objenesis:objenesis:jar:1.1:compile
[INFO] |  +- ognl:ognl:jar:2.7.3:compile
[INFO] |  |  \- jboss:javassist:jar:3.7.ga:compile
[INFO] |  +- com.thoughtworks.paranamer:paranamer:jar:2.2:compile
[INFO] |  +- org.springframework:spring-aop:jar:3.0.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-asm:jar:3.0.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:3.0.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-context:jar:3.0.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-core:jar:3.0.5.RELEASE:compile
[INFO] |  |  \- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] |  +- org.springframework:spring-expression:jar:3.0.5.RELEASE:compile
[INFO] |  +- org.springframework:spring-web:jar:3.0.5.RELEASE:compile
[INFO] |  +- org.aspectj:aspectjrt:jar:1.6.9:compile
[INFO] |  +- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  +- net.sf.scannotation:scannotation:jar:1.0.2:compile
[INFO] |  |  \- javassist:javassist:jar:3.6.0.GA:compile
[INFO] |  \- jfree:jfreechart:jar:1.0.12:compile
[INFO] |     \- jfree:jcommon:jar:1.0.15:compile
[INFO] +- opensymphony:sitemesh:jar:2.4.2:compile
[INFO] +- junit:junit:jar:4.8.2:test
[INFO] +- javax.servlet:jstl:jar:1.2:compile
[INFO] +- org.hibernate:hibernate-core:jar:3.6.4.Final:compile
[INFO] |  +- antlr:antlr:jar:2.7.6:compile
[INFO] |  +- commons-collections:commons-collections:jar:3.1:compile
[INFO] |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO] |  +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile
[INFO] |  +- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.0.Final:compile
[INFO] |  \- javax.transaction:jta:jar:1.1:compile
[INFO] +- org.hibernate:hibernate-validator:jar:4.0.2.GA:compile
[INFO] |  +- javax.xml.bind:jaxb-api:jar:2.1:compile
[INFO] |  |  +- javax.xml.stream:stax-api:jar:1.0-2:compile
[INFO] |  |  \- javax.activation:activation:jar:1.1:compile
[INFO] |  \- com.sun.xml.bind:jaxb-impl:jar:2.1.3:compile
[INFO] +- javax.validation:validation-api:jar:1.0.0.GA:compile
[INFO] +- mysql:mysql-connector-java:jar:5.1.16:compile
[INFO] \- org.mockito:mockito-all:jar:1.8.5:test

edit—
lucas, nao estamos errando as versoes ? pois dentro dos jars mencionados acima nao existe org.hibernate.validator.ClassValidator

abrassss

ah tah… é pq essa é uma classe do HV3…

troque o HibernateMockValidator pelo JSR303MockValidator que vai funcionar

[]'s

Perfeito Lucas, agora está tudo certo. MUITO OBRIGADO.

agora tenho como testar os controllers, ufa.

Porém adicionei como uma classe do meu projeto mesmo… futuramente, esta classe vai estar embutida no vraptor ?

abrassss

sim… se vc não se importar em usar um snapshot, já está embutida…

mude a versão do vraptor pra 3.4.0-SNAPSHOT e adicione esse snapshot repository no pom:

https://oss.sonatype.org/content/repositories/snapshots