Vraptor e mockito - testes de controllers

15 respostas
renanreismartins

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

15 Respostas

Lucas_Cavalcanti

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.

renanreismartins

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

renanreismartins

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

Lucas_Cavalcanti

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

renanreismartins

Excelente!

funcionou lindo… controllers testados!

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

abrasssss

Lucas_Cavalcanti

classNotFound em qual classe?

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

renanreismartins

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

Lucas_Cavalcanti

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

renanreismartins

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

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

obrigado lucas

abrasss

renanreismartins

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

Lucas_Cavalcanti

roda:

mvn dependency:tree

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

renanreismartins

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

Lucas_Cavalcanti

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

troque o HibernateMockValidator pelo JSR303MockValidator que vai funcionar

[]'s

renanreismartins

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

Lucas_Cavalcanti

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

Criado 1 de junho de 2011
Ultima resposta 4 de jun. de 2011
Respostas 15
Participantes 2