Problem
Trying to create unit test to the method persist from a class created in Spring Roo using a stub do the EntityManger that is passed in the constructor as follows:
public class ClassATest {
@Test
public void whenPersistShoulCallClassB() throws Exception {
Mockery contexto = new Mockery();
final ClassB classB = contexto.mock(ClassB.class);
final ClassA classA =
new ClassA(getEntityManagerStub(), classB);
contexto.checking(new Expectations() {{
one(classB).doSomething(classA);
}
});
classA.persist();
contexto.assertIsSatisfied();
}
private EntityManager getEntityManagerStub() {
return new EntityManager() {
...
}
}
}
Source from ClassA
public class ClassA {
...
public ClassA(EntityManager entityManager, ClassB classB) {
this.entityManager = entityManager;
this.classB = classB;
}
@Transactional
public void persist() {
if (this.entityManager == null) this.entityManager = entityManager();
this.entityManager.persist(this);
classB.doSomething(this);
}
...
}
This test works inside Eclipse, but doesn´t when called by maven, as a result of mvn jetty:run-exploded.
Reason
Probably Spring Roo is injecting the EntityManager just before the call to the constructor.
Solution
Use of setter injection, as follows:
public class ClassATest {
@Test
public void whenPersistShoulCallClassB() throws Exception {
Mockery contexto = new Mockery();
final ClassB classB = contexto.mock(ClassB.class);
final ClassA classA =
new ClassA(classB);
classeA.setEntityManager(getEntityManagerStub());
contexto.checking(new Expectations() {{
one(classB).doSomething(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.doSomething(this);
}
...
}
There must be a more elegant solution that enables the utilization of construction injection. When I have time to research, I will post it
.