Big Bad Baerni
Big Bad Baerni

Reputation: 996

Injection of @alternative bean with code, instead of beans.xml

We're testing an EJB with EJBContainer in JUnit. Another EJB called by the tested bean is mocked by the test with an @alternative bean. This mock bean is configured as <alternative> in beans.xml

Everything works as like a charm, the EJB is tested and uses the mocked service.

Question: Is it possible to do the same only with code, instead of using a beans.xml?

Of course a beans.xml gives good flexibility, though sometimes one might want to have a different @alternative for the same bean and the possibility to select one specific for a single/other test in the same project. Perhaps another solution would be a specific beans.xml for certain tests (with the question how to select it)?

Some of our test code (ExtensionMock is called by the tested EchoRemote implementation and part of the tests):

public class EchoTest {
private EJBContainer ejbContainer;
private Context ctx;


@Before
public void setUp() throws NamingException {
    ejbContainer = EJBContainer.createEJBContainer();
    ctx = ejbContainer.getContext();
}

@After
public void tearDown() {
    ejbContainer.close();
}

@Test
public void testFindAll() {
    try {
        EchoRemote userEJB = (EchoRemote) ctx.lookup("java:global/ssb-ejb/Echo!examples.ssb.EchoRemote");
        assertNotNull(userEJB);
        assertEquals("Hello World", userEJB.echo("Hello World"));
    } catch (NamingException e) {
        throw new AssertionError(e);
    }
}

}

<beans>

    <alternatives>
        <class>examples.ssb.EchoExtensionMock</class>
    </alternatives>

</beans>

Upvotes: 3

Views: 1706

Answers (3)

ab100
ab100

Reputation: 88

Instead of creating an independent @Alternative implementation you can extend an existing one and annotate it with @Specializes.

See also: http://docs.oracle.com/javaee/6/api/javax/enterprise/inject/Specializes.html

Upvotes: 3

Boris Pavlović
Boris Pavlović

Reputation: 64632

Leave the beans.xml alternative section empty. Annotate the test class with

@RunWith(org.jglue.cdiunit.CdiRunner.class)
@org.jglue.cdiunit.ActivatedAlternatives(EchoExtensionMock.class)
public class MyTest {
...

Or even better annotate the class with the same runner but produce an alternative mock:

@RunWith(org.jglue.cdiunit.CdiRunner.class)
public class MyTest {

  @Produces
  @org.jglue.cdiunit.ProducesAlternative
  @org.mockito.Mock
  private EchoExtensionMock echoExtension;

  @Inject
  private EchoRemote echoRemote;

  @Test
  public void test() throws Exception {
    Mockito.when(echoExtension.someMethod()).thenReturn(new Object());

    // here comes the testing code
  }

Upvotes: 1

LightGuard
LightGuard

Reputation: 5378

You may be able to do this with an extension, but I've never tried.

Upvotes: 1

Related Questions