【问题标题】:CDI injection and JUnitCDI 注入和 JUnit
【发布时间】:2017-10-25 09:46:23
【问题描述】:

我正在尝试将 JUnit 测试添加到使用 CDI 和 JPA 的 Tomee Web 应用程序中。撇开过去两周的不同障碍(包括对 stackoverflow 以及其他来源的深入研究),我的问题似乎非常具体:

运行单元测试会给出以下错误消息:

org.apache.openejb.Injector$NoInjectionMetaDataException: 
org.demo.service.GenericServiceTest : Annotate the class with @javax.annotation.ManagedBean so it can be discovered in the application scanning process
    at org.apache.openejb.Injector.inject(Injector.java:54)
    at org.apache.openejb.OpenEjbContainer$GlobalContext.bind(OpenEjbContainer.java:656)
...

这个我不明白,因为我已经按要求对类进行了注释。知道我能做些什么来解决这个问题吗?

(或者错误是指注入的类 - GenericService?我无法注释这个@ManagedBean,因为它已经是@Stateless)。

以下是我的项目的一些细节:

gradle 依赖:

dependencies {

    compile 'org.apache.commons:commons-lang3:3.3.2'
    compile "com.googlecode.json-simple:json-simple:1.1.1"
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.8.6'
    compile group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.8.6'
    compile 'log4j:log4j:1.2.16'
    testCompile "org.apache.openejb:tomee-embedded:1.7.3"
    compile "javax:javaee-api:7.0"
    compile 'mysql:mysql-connector-java:5.1.16'
}

(我把testCompile放在中间了,因为有一张单子说明顺序的重要性:EJB testing with TomEE embedded EJBContainer api: java.lang.ClassFormatError exception)

我的测试课是这样的:

package org.demo.service;

import java.io.File;
import java.util.Properties;

import javax.annotation.ManagedBean;
import javax.ejb.embeddable.EJBContainer;
import javax.inject.Inject;
import javax.naming.NamingException;

import org.apache.openejb.OpenEjbContainer;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

@ManagedBean
public class GenericServiceTest {
    private static EJBContainer ejbContainer;

    @Inject
    private GenericService service;

    @Test
    public void test() throws NamingException {
        System.out.println("service: " + service);
    }

    @BeforeClass
    public static void start() {
        Properties p = new Properties();
        try {
            p.put(EJBContainer.MODULES, new File("bin"));
        } catch (Exception e1) {
            e1.printStackTrace();
        }
        p.put(OpenEjbContainer.Provider.OPENEJB_ADDITIONNAL_CALLERS_KEY, GenericService.class.getName());
        ejbContainer = javax.ejb.embeddable.EJBContainer.createEJBContainer(p);
    }

    @Before
    public void inject() throws NamingException {
        ejbContainer.getContext().bind("inject", this);
    }

    @AfterClass
    public static void shutdownContainer() {
        if (ejbContainer != null) {
            ejbContainer.close();
        }
    }
}

也许我在这里完全走错了方向 - 如果我应该选择不同的方法,请告诉我 - 我想要的只是将单元测试添加到我的 Web 应用程序(最好不引入 Weld/JBoss 或其他实现作为替代我已经在应用程序本身中使用的实现)。

非常感谢您!

【问题讨论】:

  • @ManagedBean 不是 CDI bean。你的方向完全错误。尝试使用 Arquillian - Arquillian 提供您想要的。

标签: junit ejb cdi openjpa apache-tomee


【解决方案1】:

我建议你阅读http://tomee.apache.org/developer/testing/index.html,有一些例子

关于您的测试,它使用 openejb 嵌入式而不是 tomee 嵌入式并将 bin/ 部署为应用程序。 hack bind("inject") 仅适用于类路径部署(无模块)。

【讨论】:

  • 感谢 Romain - 这真的很有帮助! JUnits 现在正在运行。回一个问题:我正在使用:@RunWith(SingleApplicationComposerRunner.class) 和一个带有@Classes 注释的模型类,以包含所有要注入的类——这可能会变得很多。有没有办法包含要扫描 CDI 的目录?
  • (at)默认将设置“当前”模块(org.apache.openejb 之一)和 (at)Jars 可以匹配类路径上的文件名 - ~ 模块名。
猜你喜欢
  • 2018-01-19
  • 2014-02-28
  • 2019-05-05
  • 1970-01-01
  • 2016-06-07
  • 2015-02-12
  • 2012-06-28
  • 2013-09-17
  • 1970-01-01
相关资源
最近更新 更多