Search code examples
javaunit-testingjakarta-eeejbjboss-arquillian

How to invoke a stateless bean method if it is not declared in interface implementing the business logic


I am not so experienced in EJBs, especially EJB 3.0 and thus, I faced out with a question I would like to resolve. A similar issue I have found here, but the suggested solution did not help.

I have a remote stateless EJB with its business methods declared in interface and the bean which implements those methods has also other methods which are not declared in interface.

As an example here is the business interface:

public interface BusinessLogic {
    Object create();
    void delete(Object x);
}

A BusinessLogicBean which implements the business logic:

@Stateless
@Remote(BusinessLogic.class)
public class BusinessLogicBean implements BusinessLogic {

    /** implemented method */
    public Object create() {
        Object x = new SomeDBMappedObject();
        // create an object in DB and return wrapper class
        ...
        return x;
    }

    /** implemented method */
    public void delete(Object x) {
        // deleting object from DB
        ...
    }

    /** The method that performs some extra logic */
    public void aMethod() {
        // do extra logic
    }
}

I need to write unit tests for that EJB using Arquillian framework including for the bean methods which are not declared in the business interface.

Example:

@RunWith(Arquillian.class)
public class BusinessLogicTest {

    /** will be injected during the test run */
    @EJB
    private BusinessLogic businessLogic;

    @Deployment
    public static Archive createDeployment() {
        WebArchive war = ShrinkWrap.create(WebArchive.class, "test.war")
                // add needed libraries and classes
                .addAsWebInfResource(EmptyAsset.INSTANCE, "beans.xml");

        return war;
    }

    @Test
    public void aMethodTest() {
        businessLogic.aMethod();

        // Write appropriate assertions
    }
}

My questions are:

  • how can I call aMethod() in my test? I cannot call it like businessLogic.aMethod();, since it will result in a compilation error. I cannot call it like ((BusinessLogicBean) businessLogic).aMethod();, as it will result in a ClassCastException since the actual object is a com.sun.proxy.$ProxyXXX type. or
  • Is there a way to inject BusinessLogicBean object directly instead of BusinessLogic?

Solution

  • You can annotate BusinessLogicBean with @javax.ejb.LocalBean

    @Stateless
    @LocalBean
    @Remote(BusinessLogic.class)
    public class BusinessLogicBean implements BusinessLogic {
    ...
    }
    

    and inject it by its class name:

    @EJB BusinessLogicBean businessLogicBean;
    

    See also: