Тестирование ejb с заглушкой и фреймворком openejb

Я пытаюсь протестировать EJB, в который вставлен еще один. Для целей тестирования я хочу использовать заглушку для внедренного EJB. Я использовал openEJB в качестве основы для EJB для тестирования.

Вот EJB:

@Stateless
@Local(IService.class)
public class Service implements IService {

    @EJB
    private IBean bean;

    @Override
    public String doService(String data) {
        return bean.process(data);
    }
}

Настоящий внедренный EJB:

@Stateless
@Local(IBean.class)
public class Bean implements IBean {

    private static Logger logger = Logger.getLogger(Bean.class);

    @Override
    public String process(String data) {
        logger.info("Bean processing : " + data);
        return "Bean processing : " + data;
    }
}

Заглушка версии EJB:

@Stateless
@Local(IBean.class)
public class BeanStub implements IBean {

    private static Logger logger = Logger.getLogger(BeanStub.class);

    @Override
    public String process(String data) {
        logger.info("Stub processing : " + data);
        return "Stub processing : " + data;
    }
}

И тест JUnit использовал:

public class ServiceTest {

    private static Logger logger = Logger.getLogger(ServiceTest.class);

    private static InitialContext context;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        // openEJB
        Properties p = new Properties();
        p.put(Context.INITIAL_CONTEXT_FACTORY,"org.apache.openejb.client.LocalInitialContextFactory");
        p.put("openejb.altdd.prefix", "stub"); // use specific ejb-jar
        p.put("openejb.descriptors.output", "true");

        context = new InitialContext(p);
    }

    @Test
    public void testServiceStub() {
        try {
            IService service = (IService) context.lookup("ServiceStubLocal");
            assertNotNull(service);
            String msg = service.doService("service");
            assertEquals("Stub processing : service", msg);
        } catch (NamingException e) {
            logger.error(e);
            fail(e.getMessage());
        }
    }
}

Я попытался переопределить использование реального EJB заглушкой, используя конкретный ejb-jar (я хочу использовать «BeanStub» вместо «Bean» по умолчанию в моей службе):

 <ejb-jar>
    <enterprise-beans>
    <session id="ServiceStub">
        <ejb-name>ServiceStub</ejb-name>
        <ejb-class>tests.Service</ejb-class>
        <ejb-local-ref>
            <ejb-ref-name>tests.Service/bean</ejb-ref-name>
            <ejb-link>BeanStub</ejb-link>
        </ejb-local-ref>
    </session>          
    </enterprise-beans>
</ejb-jar> 

К сожалению, у меня проблема с объявлением EJB:

    Apache OpenEJB 3.1.4    build: 20101112-03:32
http://openejb.apache.org/
17:14:29,225  INFO startup:70 - openejb.home = D:\Workspace_Java\tests\testejb
17:14:29,225  INFO startup:70 - openejb.base = D:\Workspace_Java\tests\testejb
17:14:29,350  INFO config:70 - Configuring Service(id=Default Security Service, type=SecurityService, provider-id=Default Security Service)
17:14:29,350  INFO config:70 - Configuring Service(id=Default Transaction Manager, type=TransactionManager, provider-id=Default Transaction Manager)
17:14:29,381  INFO config:70 - Found EjbModule in classpath: D:\Workspace_Java\tests\testejb\target\test-classes
17:14:29,412  INFO config:70 - Found EjbModule in classpath: D:\Workspace_Java\tests\testejb\target\classes
17:14:29,428  INFO config:70 - Beginning load: D:\Workspace_Java\tests\testejb\target\test-classes
17:14:29,428  INFO config:70 - AltDD ejb-jar.xml -> file:/D:/Workspace_Java/tests/testejb/target/test-classes/META-INF/stub.ejb-jar.xml
17:14:29,850  INFO config:70 - Beginning load: D:\Workspace_Java\tests\testejb\target\classes
17:14:29,850  INFO config:70 - AltDD ejb-jar.xml -> file:/D:/Workspace_Java/tests/testejb/target/classes/META-INF/stub.ejb-jar.xml
17:14:29,850  INFO config:70 - Configuring enterprise application: classpath.ear
17:14:29,912  INFO config:70 - Configuring Service(id=Default Stateless Container, type=Container, provider-id=Default Stateless Container)
17:14:29,912  INFO config:70 - Auto-creating a container for bean ServiceStub: Container(type=STATELESS, id=Default Stateless Container)
17:14:29,912  INFO options:70 - Using 'openejb.descriptors.output=true'
17:14:29,912  INFO options:70 - Using 'openejb.descriptors.output=true'
17:14:29,928  INFO config:70 - Dumping Generated ejb-jar.xml to: C:\TEMP\ejb-jar-6391test-classes.xml
17:14:29,959  INFO config:70 - Dumping Generated openejb-jar.xml to: C:\TEMP\openejb-jar-6392test-classes.xml
17:14:29,959  INFO options:70 - Using 'openejb.descriptors.output=true'
17:14:29,959  INFO config:70 - Dumping Generated ejb-jar.xml to: C:\TEMP\ejb-jar-6393classes.xml
17:14:29,975  INFO config:70 - Dumping Generated openejb-jar.xml to: C:\TEMP\openejb-jar-6394classes.xml
17:14:30,006  INFO config:70 - Enterprise application "classpath.ear" loaded.
17:14:30,084  INFO startup:70 - Assembling app: classpath.ear
17:14:30,131  INFO startup:70 - Jndi(name=ServiceStubLocal) --> Ejb(deployment-id=ServiceStub)
17:14:30,131 ERROR startup:46 - Jndi name could not be bound; it may be taken by another ejb.  Jndi(name=openejb/Deployment/ServiceStub/tests.IService!Local)
17:14:30,131  INFO startup:70 - Undeploying app: classpath.ear
17:14:30,147 ERROR startup:50 - Application could not be deployed:  classpath.ear
org.apache.openejb.OpenEJBException: Creating application failed: classpath.ear: Unable to bind business local interface for deployment ServiceStub
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:679)
    at org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:450)

Что-то не так в подходе или в способе написания ejb-jar?


person Frederic    schedule 11.03.2011    source источник


Ответы (2)


У меня были похожие проблемы и препятствия с OpenEJB. Если вам нужны заглушки и насмешки для тестов (кому это не нужно), посмотрите, кому мне наконец удалось с этим справиться (с большой помощью Дэвида — соучредителя OpenEJB). В последней версии (3.1.4) OpenEJB работает почти так же, как Arquillian, позволяя тестировать драйвер внутреннего класса без сканирования ejb-jar.xml и пути к классам.

Я описал свои препятствия здесь: http://jakub.marchwicki.pl/posts/2011/07/01/testing-ejb-application-openejb-without-classpath-scanning/. Посмотрите, может быть, это облегчит вам тестирование.

person Jakub Marchwicki    schedule 02.07.2011
comment
URL возвращает 404 - person Jasper; 26.09.2014
comment
Извините за это, он снова онлайн. Я очень лениво перемещаю блог, и не все статьи снова доступны в сети. - person Jakub Marchwicki; 02.11.2014
comment
Ссылка не работает. - person Keppil; 08.07.2016

Почему бы вам просто не использовать фиктивную среду, такую ​​​​как EasyMock или Mockito, чтобы проверить это. Вам не понадобится какой-либо дескриптор развертывания, контейнер EJB, поиск JNDI и т. д. Просто такой код:

@Test
public void testDoService() {
    IBean mockBean = EasyMock.createMock(IBean.class);
    mockBean.process("data");
    EasyMock.replay(mockBean);

    Service serviceToTest = new Service(mockBean);
    serviceTotest.doService("data");
    EasyMock.verify(mockBean);
}

И он, безусловно, будет работать намного быстрее.

person JB Nizet    schedule 11.03.2011
comment
Спасибо, за такой простой случай, который может быть решением, кроме того, что это всего лишь один из примеров проблемы, реальный случай намного сложнее и также включает доступ к базе данных и более сложные действия внутри заглушки. - person Frederic; 13.03.2011