1

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?
Community
  • 1
  • 1
Armine
  • 1,675
  • 2
  • 24
  • 40
  • I think you're mixing two types of tests here: on one side you have integration tests, where you can test, for instance, the remote call to your `BusinessLogic`'s `create` and `delete` methods; on the other hand, you have unitary tests where you can individual test a piece of source code, for instance, your business logic implementation: `BusinessLogicBean`. So, you can keep the usage of Arquillian for your integration tests but you should create a test case, using only JUnit, for the unitary tests of your `BusinessLogicBean`. – António Ribeiro May 03 '16 at 13:17
  • Dear @aribeiro, I would be agree with you if the method I wanted to test was only an internal business logic. That piece of functionality affects too many things in my EJB and hence its testing needs to be included in integration test. You may ask: then why it is not included in business interface? But it's because it was already written in that way (before I started to work on it), and I don't want to change it. Anyway, thanks for your comment and interest. – Armine May 05 '16 at 11:40
  • You're welcome. :) Well, since you're already adding a *beans.xml* to your deployment, you could always try using CDI and `@Inject` your `BusinessLogicBean` into your test. – António Ribeiro May 05 '16 at 12:21

1 Answers1

1

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:

Community
  • 1
  • 1
Linuslabo
  • 1,568
  • 2
  • 24
  • 34