Тестирование ejb с фреймворком stub и openejb - PullRequest
1 голос
/ 11 марта 2011

Я пытаюсь проверить 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?

Ответы [ 2 ]

1 голос
/ 03 июля 2011

У меня были похожие проблемы и проблемы с 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/. Посмотрите, может быть, это облегчит вам тестирование.

0 голосов
/ 11 марта 2011

Почему бы вам просто не использовать макет, такой как 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);
}

И он, конечно, тоже будет работать намного быстрее.

...