在 CDI-Unit 中注入 @PersistenceContext

2024-01-08

这是单元测试代码。当我们运行单元测试代码(SampleServiceTest2)时; AbstractDao 中注入的 EntityManager 始终为 null!我们如何在单元测试期间注入 em。

*** 示例服务测试2.java

import javax.inject.Inject;

import org.jglue.cdiunit.CdiRunner;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(CdiRunner.class)
public class SampleServiceTest2 {

    @Inject SampleService greeter; 

    @Test
    public void testGreeter() throws Exception { 
        System.out.println("before2");
        greeter.addSampleData(new SampleDataDto(), new KullaniciDto()); 
        System.out.println("after2");
    } 
}

*** 示例服务.java

import javax.ejb.Stateless;
import javax.inject.Inject;
....

@Stateless
@SecuredBean
public class SampleService {

    @Inject 
    SampleLogic sampleLogic;

    @Yetki(tag="perm_add_sample_data")
    public void addSampleData(SampleDataDto data, KullaniciDto aktifKullaniciDto){
        SampleDataHelper sampleDataHelper = new SampleDataHelper();

        SampleData sampleData = sampleDataHelper.getEntity(data);
        KullaniciHelper kullaniciHelper = new KullaniciHelper();

        Kullanici kullanici = kullaniciHelper.getEntity(aktifKullaniciDto);
        sampleLogic.addData(sampleData, kullanici);
    }

}

**** 示例逻辑.java

import javax.inject.Inject;

....

public class SampleLogic {
    @Inject 
    SampleDataDao sampleDataDao;

    public void addData(SampleData data, Kullanici kullanici) {
        addData1(data,kullanici);   
        System.out.println("SampleLogic : addData() called!");
    }

    public void addData1(SampleData data, Kullanici kullanici) {
        sampleDataDao.create(data, kullanici);
    }
}

**** SampleDataDao.java

public class SampleDataDao extends AbstractDao<SampleData> {
    private static final long serialVersionUID = 1L;
}

**** AbstractDao.java

public abstract class AbstractDao<T extends BaseEntity> implements Serializable {

    private static final long serialVersionUID = 1L;

    @PersistenceContext(unitName="meopdb")
    private EntityManager em;

    protected EntityManager getEm() {
        return em;
    }

    @SuppressWarnings("rawtypes")
    private Class entityClass;


    @SuppressWarnings("rawtypes")
    private Class getEntityClass() {
        if (entityClass == null) {
            entityClass = (Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        }
        return entityClass;
    }

    public T create(T t, Kullanici kullanici) {
        if (t.getId() != null) {
            throw new IllegalStateException("Create Operation: Oid should be null");
        }
        t.setId(getSeqNextValue(t));
        t.setEklemeZamani(new Timestamp(Calendar.getInstance().getTimeInMillis()));
        t.setEkleyenKullaniciId(kullanici.getId());

        t.setDurumId(EnumDurum.AKTIF.getValue());

        t = em.merge(t);
        em.flush();
        return t;
    }
}

如果您使用 CDIUnit 进行测试,您获得的唯一结果就是 CDI 注入,而不是 Java EE 的全部功能。使用注入entityManager@PersistenceContext into AbstractDAO不是独立 CDI 的一部分,仅当应用程序在 Java EE 应用程序服务器中运行时才受支持。

解决方案是使用CDI机制注入EntityManager并创建生产者。然后可以在单元测试中切换生产者以提供测试实体管理器。但是,在独立单元测试中设置 JPA 并不那么简单,因为您需要直接在 persistence.xml 文件中指定连接属性。另外,不要忘记将 JPA 实现(hibernate、eclipselink)的依赖项添加到测试依赖项中。

但是,如果您不想调整应用程序的代码或者您在测试中需要的不仅仅是 CDI,那么您应该看看Arquillian Java EE 测试框架 http://arquillian.org/.

以下是 CDIUnit 的示例:

public abstract class AbstractDao<T extends BaseEntity> implements Serializable {
...
    @Inject
    @Named("meopdb")
    private EntityManager em;
...
}

// producer in application - just a wraper over `@PersisteneContext`
public class EntityManagerProducer {
    @Produces
    @PersistenceContext(unitName="meopdb")
    @Named("meopdb")
    private EntityManager em;
}

/* producer in your test sources - it creates entityManager via API calls instead of injecting via `@PersistenceContext`. Also, a different persistence unit is used so that it does not clash with main persistence unit, which requires datasource from app server 
*/
public TestEntityManagerProducer {
    @Produces
    @ProducesAlternative // CDIUnit annotation to turn this on as an alternative automatically
    @Named("meopdb")
    public EntityManager getEm() {
        return Persistence
                .createEntityManagerFactory("meopdb-test")
                .createEntityManager();
    }

}

但这还不够。您需要创建一个新的persistence.xml在您的测试资源中,测试持久性单元名为“meopdb-test”。对于此单位,您需要指定RESOURCE_LOCAL transaction-type,并指定连接信息。最后不要忘记 - 您需要在 persistence.xml 或外部 orm 文件中列出所有实体。这是因为您的测试在应用程序服务器之外运行。在应用程序服务器内部,JPA 可以自动查找实体。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 CDI-Unit 中注入 @PersistenceContext 的相关文章

随机推荐

  • setInterval 在非活动选项卡上不会减慢速度

    这可能与一个非常常见的问题相反 当您使用setInterval在一个选项卡上切换到另一个选项卡时 间隔会显着缩短 即减慢 这对于音频计时来说非常明显 因为您可以听到它被减慢的声音 但在最新的 Chrome 56 和 Firefox 51 上
  • WPF:为什么消息框标题栏上没有图标

    我想要的只是我的消息框应该在其标题栏中显示我的应用程序的图标 或任何其他图标 但它没有 为什么不呢 The MessageBox in WPF http msdn microsoft com en us library system win
  • 如何在 PHP 中找到拼写错误的相似单词?

    我将解释我的问题 我有一个名为country 它有两列 ID and name 当我想要寻找的时候 paris 但拼写错误 pares e 代替 i 我不会从数据库得到任何结果 我希望系统建议可以帮助搜索的相似单词 因此 我正在寻求帮助编写
  • 返回特定属性的默认 get 方法 - MATLAB

    我正在重构一些 MATLAB 遗留软件 涉及在广泛的测试中获得的数据 我正在尝试创建一个包含每个单独通道的数据以及一些额外信息 例如其物理单位 的类 只是为了将这个问题放在这里 该类可以如下所示 classdef Channel lt ha
  • 在字符串时间中添加 20 分钟并将其填充到文本框中或提醒它

    我在选择 列表控件中填充了一个时间字符串 例如 05 40 我想在其中添加 20 分钟 并在每次列表值在 jquery 或 javascript 中发生更改时填充在文本框中 document ready function starttime
  • 如何使用 Amazon EKS 上的 kubernetes 入口控制器将 http 重定向到 https

    我已经为我的应用程序配置了亚马逊证书管理器 ALB 入口控制器和域名 我可以通过端口 80 和端口 443 访问我的应用程序 所有证书都可以正常工作 但是 我想自动将所有来自 HTTP 的流量重定向到 HTTPS 以便自行输入域名的人被重定
  • 如何从 PHP 执行交互式命令?

    我需要执行kdiff3从 PHP 脚本在我的桌面计算机 localhost 中运行命令 使用浏览器 而不是命令行 我已授予用户权限www data正在执行脚本来执行 kdiff3 使用visudo 事实上 如果我登录为www data我可以
  • 如何在 QuickCheck (Haskell) 中使用“oneof”

    我正在尝试编写一个更改数独的道具 然后检查它是否仍然有效 但是 我不确定如何正确使用 oneof 函数 您能给我一些提示吗 prop candidates Sudoku gt Bool prop candidates su isSudoku
  • 无论如何,在不设置 https 连接的情况下设置 Telegram Webhook

    我想设置Telegram Webhook但我没有httpsURL 我也不想处理 ssl 证书 我可以通过使用 https URL 或不设置来解决这个问题https证书上了吗 Telegram webhook 描述 https core te
  • Android 将 apk 安装到设备时出现 [SEGMENTATION FAULT]

    我有个问题 当我尝试使用 AndroidStudio 部署 调试或运行 我的应用程序时 我在 RunLog 中收到以下错误 Waiting for device Target device samsung galaxy nexus WOVC
  • 混淆 JavaScript 属性?

    我最近测试过UglifyJS https github com mishoo UglifyJS and YUI压缩器 http developer yahoo com yui compressor 并注意到一些奇怪的事情 两个缩小器似乎都没
  • 如何在 Chrome 扩展中自定义弹出窗口的标题栏?

    如何在 Chrome 扩展中设置弹出窗口标题栏的样式 我注意到这是由Chrome 聊天室 https chrome google com webstore detail chat for google nckgahadagoaajjgafh
  • 使用 JQ 修改嵌套 JSON 数组

    我想使用 JQ 修改以下 JSON 输入 rows fields name id value k1 name val value 2340378b211aa3d8f2d7607cbddce883b87b191d0425736641e3d30
  • Firefox 中出现奇怪的 CSP 错误

    我最近添加了以下 CSP 策略https stefan sofa rockers org https stefan sofa rockers org default src self style src self https brick a
  • 如何在 Maven 中创建两个文件的一个校验和以在目录名称中使用它

    我正在使用 Maven 创建一个目录 本地 Eclipse b3 Aggregator P2 镜像 两个配置文件 A target B target 用于两次创建此目录 如果这些配置文件发生更改 则应创建新的镜像目录 我想将配置文件的校验和
  • 使本地 TFS 构建代理使用 v14 msbuild 工具

    我有几个 ASP NET vNext 应用程序 我希望我的 CI 服务器也能够构建它们 我的本地机器和 CI 服务器都运行 VS2015 RC 然后我们就有了 VS Online 和本地构建控制器 这就是提到的服务器 但是 我无法继续构建
  • Lua 要求不工作

    我正在尝试使一个 lua 文件需要另一个文件 我正在遵循本指南 http lua users org wiki ModulesTutorial http lua users org wiki ModulesTutorial 我的基本测试应该
  • 获取 USB HDD 的序列号 (Mac OS)

    我已经在 stackoverflow com 和 google 上搜索了答案 但找不到任何东西 我获得了属于外部 USB HDD disk1 的分区 disk1s1 的 bsdName 我需要找出该外部硬盘的序列号 我已经尝试过以下操作 查
  • SCSS 模块给出流程错误

    更新至Create React App 2它通过以下 import 语句支持 css 模块 import styles from myStyles module scss 然而 flow正在抱怨说 Importing from an unt
  • 在 CDI-Unit 中注入 @PersistenceContext

    这是单元测试代码 当我们运行单元测试代码 SampleServiceTest2 时 AbstractDao 中注入的 EntityManager 始终为 null 我们如何在单元测试期间注入 em 示例服务测试2 java import j