How to mock services with Arquillian?

Teliatko picture Teliatko · Feb 28, 2011 · Viewed 10.7k times · Source

Is it possible to use some kind of mocking framework with Arquillian, or precisely how to mock injected EJBs? I know that, with using the CDI (Contexts and Dependency Injection), it is possible to inject alternatives in test. But without CDI as injection mechanism, when I'm only using EJB injection, how this is possible?

Recently I have tested my EJBs with service interface mock implementation as following:

// Service inteface 
public interface Audit {
   void audit(String info);
}

// Mock implementation
@Stateless
public class MockAuditBean implements Audit {

    public static String lastInfo = null;

    @Override
    public void audit(String info) {
        this.lastInfo = info;
    }
}

// assert in test
assertTrue(MockAuditBean.lastInfo.contains("dummy"));

This approach is possible but requires a lot of custom mock implementations. What is worse, injected instances of mocks are proxies and uses service interface. These can not be cast to mock implementation class to compare results. Only static members and methods of mock implementation can be used.

I have tested also another possibilities to set related EJBs manually. This approach has several draw-backs. It requires that target EJB of test has non-private members or setters for them. When target EJB relies on @PostConstruct lifecycle annotation, you have to call it after your manual "injection" setting. Advantage of this solution is the ability to use mock frameworks, like mockito or jMock.

Have someone an experience to share, how to test and set-up such integration test, or even use mocking frameworks in it ?

Answer

Cloves Almeida picture Cloves Almeida · May 17, 2011

IMO, EJBs where not designed with testing in mind. Your alternative sounds like a good enough compromise and I'd go for it. Using mockito is a major plus and I use it even when working with CDI.

I'd use the "default" member scope and javadoc to other developers access them for testing purposes only.