PeterPan333
PeterPan333

Reputation: 1

Rewrite JMockit Mockup to Mockito: Interception of method calls of dependency api

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

Answers (0)

Related Questions