Ao tentar criar testes de unidade para o método persist de uma classe criada pelo Spring Roo, tentei utilizar um Stub para o EntityManager da seguinte forma:
public class ClasseATest { @Test public void aoPersistirDeveriaChamarClasseB() throws Exception { Mockery contexto = new Mockery(); final ClasseB classeB = contexto.mock(ClasseB.class); final ClasseA classeA = new ClasseA(getEntityManagerStub(), classeB); contexto.checking(new Expectations() {{ one(classeB).fazerAlgo(classeA); } }); classeA.persist(); contexto.assertIsSatisfied(); } private EntityManager getEntityManagerStub() { return new EntityManager() { ... } } }Código da ClasseA
public class ClasseA { ... public ClasseA(EntityManager entityManager, ClasseB classeB) { this.entityManager = entityManager; this.classeB = classeB; } @Transactional public void persist() { if (this.entityManager == null) this.entityManager = entityManager(); this.entityManager.persist(this); classeB.fazerAlgo(this); } ... }
O teste funcionava quando era executado dentro de Eclipse, mas falhava quando era executado via maven, no momento da execução do mvn jetty:run-exploded.
Motivo
Provavelmente o spring roo está injetando o EntityManager logo após a chamada ao constructor.
Solução
Utilizar setter injection, como mostrado abaixo:
public class ClasseATest { @Test public void aoPersistirDeveriaChamarClasseB() throws Exception { Mockery contexto = new Mockery(); final ClasseB classeB = contexto.mock(ClasseB.class); final ClasseA classeA = new ClasseA(classeB); classeA.setEntityManager(getEntityManagerStub()); contexto.checking(new Expectations() {{ one(classeB).fazerAlgo(classeA); } }); classeA.persist(); contexto.assertIsSatisfied(); } private EntityManager getEntityManagerStub() { return new EntityManager() { ... } } }
Código da ClasseA
public class ClasseA { ... public ClasseA(ClasseB classeB) { this.classeB = classeB; } public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } @Transactional public void persist() { if (this.entityManager == null) this.entityManager = entityManager(); this.entityManager.persist(this); classeB.fazerAlgo(this); } ... }
Provavelmente deve existir uma solução mais elegante, que permita a utilização da injeção da dependência no construtor. Quando tiver tempo vou pesquisar e bloggar a solução.
No comments:
Post a Comment