Reputation: 1
Rewrite JMockit Mockup to Mockito: Interception of method calls of dependency api
I try to rewrite JMockit code (new Mockup) to Mockito. In my JUnit test a method (initializeEntityManagerInterception) is called in which interceptor methods are defined. These method should intercept methods of an non explicit referenced EntityManagerImpl object which is part of a dependency API. In my JMockit test my method setId is called correctly within the interception but not in my rewritten Mockito code. So the question is: can Mockito intercept methods of not explicit dependency objects just like JMockit does ?
protected void initializeEntityManagerInterception() throws Exception {
new MockUp<EntityManagerImpl>() {
@Mock
public void persist(Invocation i, Object o) {
setId(o); // my own written method
i.proceed(o);
}
@Mock
public Object merge(Invocation i, Object o) {
setId(o);
return i.proceed(o);
}
};
}
I tried the following mockito code but while debugging the method setId is never called:
protected void initializeEntityManagerInterception() throws Exception {
EntityManagerImpl entityManagerImpl = mock(EntityManagerImpl.class);
Answer<Void> persist = new Answer<Void>() {
public Void answer(final InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
Object obj = arguments[0];
setId(obj);
invocation.callRealMethod();
return null;
}
};
doAnswer(persist).when(entityManagerImpl).persist(any(Object.class));
Answer<Object> merge = new Answer<Object>() {
public Object answer(final InvocationOnMock invocation) throws Throwable {
Object[] arguments = invocation.getArguments();
Object obj = arguments[0];
setId(obj);
return invocation.callRealMethod();
}
};
doAnswer(merge).when(entityManagerImpl).merge(any(Object.class));
}
Adding some info: My Junit test class is subclass of a super class "BaseTest" in which method initializeEntityManagerInterception is defined. SUT is called in myTestMethod. My Class under test runs within a local jetty deployment (Apache camel route). And that's the point: With JMockit it works perfectly without explicitly injecting Mock to SUT. The Mockup definition in initializeEntityManagerInterception() was enough. Using Mockito I tried to bring in a EntityManagerImpl-Mock like in example below.
public class MyTest extends BaseTest {
private static final String BODY_PARAM = "body";
@InjectMocks
private ClassUnderTest classUnderTest;
private EntityManagerImpl entityManagerImpl;
// 1. approach of mocking
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
private Exchange exchange;
@BeforeEach
public void before() throws Exception {
super.before();
// 2. approach of mocking
entityManagerImpl = mock(EntityManagerImpl.class);
MockitoAnnotations.openMocks(this);
...
}
@Test
public void myTestMethod() throws Exception {
...
// call of class under test
classUnderTest.process(exchange);
...
Assertions.assertNotNull(params.get(BODY_PARAM));
}
}
...
public class ClassUnderTest implements Processor {
@Override
public void process(Exchange exchange) throws Exception {
EntityManagerFactory entityManagerFactory = null;
EntityManager entityManager = null;
try {
entityManagerFactory = exchange.getContext().getRegistry().lookupByNameAndType("entityManagerFactory", EntityManagerFactory.class);
entityManager = entityManagerFactory.createEntityManager();
...
entityManager.persist(someObject);
...
exchange.getMessage().setBody(someOtherObject);
}
catch(Exception ex) {
...
}
finally {
closeEntityManager(entityManager);
}
}
}
Upvotes: 0
Views: 89