【问题标题】:Testing ejb with stub and openejb framework使用 stub 和 openejb 框架测试 ejb
【发布时间】:2011-03-11 16:21:20
【问题描述】:

我正在尝试测试一个注入了另一个 EJB 的 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-jar 覆盖存根对真实 EJB 的使用(我想在我的服务中使用“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 构建:20101112-03:32 http://openejb.apache.org/ 17:14:29,225 信息启动:70 - openejb.home = D:\Workspace_Java\tests\testejb 17:14:29,225 信息启动:70 - openejb.base = D:\Workspace_Java\tests\testejb 17:14:29,350 INFO config:70 - 配置服务(id=默认安全服务,type=SecurityService,provider-id=默认安全服务) 17:14:29,350 INFO config:70 - 配置服务(id=默认事务管理器,类型=事务管理器,提供程序 id=默认事务管理器) 17:14:29,381 INFO config:70 - 在类路径中找到 EjbModule:D:\Workspace_Java\tests\testejb\target\test-classes 17:14:29,412 INFO config:70 - 在类路径中找到 EjbModule:D:\Workspace_Java\tests\testejb\target\classes 17:14:29,428 INFO config:70 - 开始加载:D:\Workspace_Java\tests\testejb\target\test-classes 17:14:29,428 信息配置:70 - AltDD ejb-jar.xml -> 文件:/D:/Workspace_Java/tests/testejb/target/test-classes/META-INF/stub.ejb-jar.xml 17:14:29,850 信息配置:70 - 开始加载:D:\Workspace_Java\tests\testejb\target\classes 17:14:29,850 信息配置:70 - AltDD ejb-jar.xml -> 文件:/D:/Workspace_Java/tests/testejb/target/classes/META-INF/stub.ejb-jar.xml 17:14:29,850 INFO config:70 - 配置企业应用程序:classpath.ear 17:14:29,912 INFO config:70 - 配置服务(id=默认无状态容器,类型=容器,提供者 id=默认无状态容器) 17:14:29,912 INFO config:70 - 为 bean ServiceStub 自动创建容器:Container(type=STATELESS, id=Default Stateless Container) 17:14:29,912 信息选项:70 - 使用 'openejb.descriptors.output=true' 17:14:29,912 信息选项:70 - 使用 'openejb.descriptors.output=true' 17:14:29,928 INFO config:70 - 将生成的 ejb-jar.xml 转储到:C:\TEMP\ejb-jar-6391test-classes.xml 17:14:29,959 INFO config:70 - 将生成的 openejb-jar.xml 转储到:C:\TEMP\openejb-jar-6392test-classes.xml 17:14:29,959 信息选项:70 - 使用 'openejb.descriptors.output=true' 17:14:29,959 INFO config:70 - 将生成的 ejb-jar.xml 转储到:C:\TEMP\ejb-jar-6393classes.xml 17:14:29,975 INFO config:70 - 将生成的 openejb-jar.xml 转储到:C:\TEMP\openejb-jar-6394classes.xml 17:14:30,006 INFO config:70 - 企业应用程序“classpath.ear”已加载。 17:14:30,084 信息启动:70 - 组装应用程序:classpath.ear 17:14:30,131 信息启动:70 - Jndi(name=ServiceStubLocal) --> Ejb(deployment-id=ServiceStub) 17:14:30,131 错误启动:46 - 无法绑定 Jndi 名称;它可能被另一个ejb占用。 Jndi(name=openejb/Deployment/ServiceStub/tests.IService!Local) 17:14:30,131 信息启动:70 - 取消部署应用程序:classpath.ear 17:14:30,147 错误启动:50 - 无法部署应用程序:classpath.ear org.apache.openejb.OpenEJBException:创建应用程序失败:classpath.ear:无法绑定业务本地接口以部署ServiceStub 在 org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:679) 在 org.apache.openejb.assembler.classic.Assembler.createApplication(Assembler.java:450)

方法有问题吗,或者写 ejb-jar 的方式有问题吗?

【问题讨论】:

    标签: java ejb-3.0 openejb


    【解决方案1】:

    我在使用 OpenEJB 时遇到了类似的问题和障碍。如果您需要对测试进行 stubbing 和 mocking(谁不需要),看看我最终设法处理了谁(在 David - OpenEJB 联合创始人的大力帮助下)。在最新版本 (3.1.4) 中,OpenEJB 的工作方式与 Arquillian 非常相似,允许内部类测试驱动程序,无需 ejb-jar.xml 和类路径扫描。

    我在这里描述了我的障碍:http://jakub.marchwicki.pl/posts/2011/07/01/testing-ejb-application-openejb-without-classpath-scanning/。看看吧,也许这会让你的测试更容易。

    【讨论】:

    • 网址返回404
    • 抱歉,它又上线了。我在移动博客的过程中非常懒惰,并非所有文章都重新上线。
    • 链接已损坏。
    【解决方案2】:

    您为什么不简单地使用像 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);
    }
    

    而且它肯定会运行得更快。

    【讨论】:

    • 谢谢,像这样一个简单的案例可以作为一个解决方案,除此之外只是一个显示问题的案例,真正的案例要复杂得多,还涉及数据库访问和存根内部更复杂的操作.
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 2014-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多