使用外星人进行测试:如何使用Arquillian测试JPA类型转换器

该帖子与+ Aslak Knutsen ( @aslakknutsen )一起撰写。

JPA类型转换器为定义实体属性如何持久存储到数据库提供了一种简便的方法。 您可以使用它们来实现许多不同的功能,例如,如上一篇文章中所示:加密数据: 如何使用JPA Type Converter加密数据 。

但是编写类型转换器还不够。 我们还需要确保其正常运行。

通常,有两种方法可以测试类型转换器。 我们可以编写一个单元测试来检查转换是否正常工作。 但是单元测试不会对隔离的类进行测试,而无需将其放入实际的执行环境中。 这意味着我们仍然不知道转换器是否可以在我们的应用程序之一中工作。 如果一切设置正确,则持久性提供程序将在写入数据库和从数据库读取之后调用转换器。 因此,我们还需要检查持久性提供程序是否调用了类型转换器,以及在这种情况下一切是否正常。 我们需要在要用于我们的应用程序的容器内测试转换器。

我们将看看如何使用Arquillian及其持久性扩展来完成此任务。

关于Arqillian

如果您已经熟悉Arquillian,则可以跳过此部分。 对于到目前为止从未与Arquillian合作的所有人,我只想提供一些基本信息。 您可以在《 Arquillian 入门指南》中找到更详细的描述。

Arquillian是用于容器测试的测试框架。 想法是不要模拟您要使用的容器,而是在其中测试您的代码。 这提供了一个优势,即您可以测试代码是否还可以在执行环境中工作,而不仅是在模拟测试场景中也可以工作。 Arquillian提供了许多功能来管理容器,注入所需的资源(如EJB或EntityManager),并使您的工作变得更加轻松。

Arquillian测试由junit执行。 这很棒,因为您可以在可以执行junit测试的任何地方使用它们。 这意味着在您的IDE中,作为构建过程的一部分,您可以在CI服务器上的任何地方。

被测对象

下面的代码片段显示了此示例中的测试对象。 它是一个类型转换器,用于加密和解密String属性。 在写入数据库和从数据库读取之后,持久性提供程序将调用转换器。 如果您想了解有关此类型转换器如何工作的更多信息,请查看我的相关文章 。

@Converter
public class CryptoConverter implements AttributeConverter<String, String> {private static final String ALGORITHM = "AES/ECB/PKCS5Padding";private static final byte[] KEY = "MySuperSecretKey".getBytes();@Overridepublic String convertToDatabaseColumn(String ccNumber) {// do some encryptionKey key = new SecretKeySpec(KEY, "AES");try {Cipher c = Cipher.getInstance(ALGORITHM);c.init(Cipher.ENCRYPT_MODE, key);return Base64.encodeBytes(c.doFinal(ccNumber.getBytes()));} catch (Exception e) {throw new RuntimeException(e);}}@Overridepublic String convertToEntityAttribute(String dbData) {// do some decryptionKey key = new SecretKeySpec(KEY, "AES");try {Cipher c = Cipher.getInstance(ALGORITHM);c.init(Cipher.DECRYPT_MODE, key);return new String(c.doFinal(Base64.decode(dbData)));} catch (Exception e) {throw new RuntimeException(e);}}
}

设定

在开始编写测试之前,我们需要定义一些依赖关系。 我将仅展示如何配置此示例所需的依赖项。 如果您尚未为项目设置Arquillian测试,则必须做更多的工作。 请查看“ 入门指南”以了解如何为您的项目设置Arquillian。 不要害怕,没有太多的事情要做。

如下面的代码片段所示,我们将使用JUnit 4.11Arquillian 1.1.3.FinalArquillian Persistence Extension 1.0.0.Alpha7WildFly Application Server 8.1.0.Final

<?xml version="1.0" encoding="UTF-8"?>
<projectxsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">...<properties><version.junit>4.11</version.junit><version.arquillian>1.1.3.Final</version.arquillian><version.arquillian_persistence>1.0.0.Alpha7</version.arquillian_persistence><version.wildfly>8.1.0.Final</version.wildfly></properties><dependencyManagement><dependencies>...<dependency><groupId>org.jboss.arquillian</groupId><artifactId>arquillian-bom</artifactId><version>${version.arquillian}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><dependencies>...<dependency><groupId>javax.enterprise</groupId><artifactId>cdi-api</artifactId><scope>provided</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${version.junit}</version><scope>test</scope></dependency><dependency><groupId>org.jboss.arquillian.junit</groupId><artifactId>arquillian-junit-container</artifactId><scope>test</scope></dependency><dependency><groupId>org.jboss.arquillian.extension</groupId><artifactId>arquillian-persistence-dbunit</artifactId><version>${version.arquillian_persistence}</version><scope>test</scope></dependency></dependencies>

编写测试

要设置测试环境,我们需要做两件事。 首先,我们需要告诉junit该测试应作为junit测试执行。 这是通过@RunWith(Arquillian.class)

此外,我们需要创建测试部署,该部署将部署到容器中。 因此,我们需要实现至少一种方法,并使用@Deployment对其进行@Deployment 。 正如您在以下代码片段中所看到的,我们使用ShrinkWrap创建jar存档部署。 存档包含CreditCard实体, CryptoConverter类型转换器和测试类。 无需包括任何实现业务逻辑的EJB或其他类。 我们可以将EntityManager注入我们的测试用例中,并直接使用它来持久化和读取实体。 稍后我们将对其进行更详细的介绍。

另外,我们需要添加一些清单资源来创建一个持久性单元,注册类型转换器并添加一个空的beans.xml来激活CDI。 请查看入门指南,以获取有关ShrinkWrap和创建部署的更多信息。

@RunWith(Arquillian.class)
public class TestCryptoConverter {@Deploymentpublic static JavaArchive createDeployment() {return ShrinkWrap.create(JavaArchive.class).addClasses(CreditCard.class, CryptoConverter.class,TestCryptoConverter.class).addAsManifestResource("META-INF/persistence.xml","persistence.xml").addAsManifestResource("META-INF/orm.xml", "orm.xml").addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml");}

完成之后,我们可以开始编写测试用例。 首先,我们将保留一个CreditCard实体并检查信用卡号是否已由CryptoConverter加密。 因此,我们注入EntityManager,创建一个CreditCard实体,并将其传递给EntityManager的persist方法。 持久化数据的验证由Arquillian持久性扩展完成。 我们只需要定义我们希望写入数据库的数据即可。 预期数据在cc.yml文件中定义,该文件在@ShouldMatchDataSet批注中引用。 由于id属性是由数据库生成的,因此我们希望将其从验证中排除。 这可以通过在注释的excludeColumns属性中引用它来完成。

@PersistenceContextprivate EntityManager em;@Test@ShouldMatchDataSet(value = "data/cc.yml", excludeColumns = "id")public void testEncryption() {CreditCard cc = new CreditCard();cc.setName("My Name");cc.setCcNumber("123456789");this.em.persist(cc);}

cc.yml包含以下信息。

CreditCard:- id: 1name: My NameccNumber: egFfkhd8cRh82tvsh3VVUg==

在第二个测试中,我们将检查是否可以在数据库中搜索具有给定信用卡号的CreditCard实体。 因此,我们使用@UsingDataSet批注为cc.yml文件中定义的数据播种数据库。 现在,我们可以使用注入的EntityManager调用命名查询,以使用给定的编号搜索CreditCard实体。

@Test@UsingDataSet("data/cc.yml")public void testRead() {CreditCard cc = this.em.createNamedQuery(CreditCard.BY_NUMBER, CreditCard.class).setParameter("number", "123456789").getSingleResult();Assert.assertEquals("My Name", cc.getName());}

结论

我们使用Arquillian和Arquillian Persistence扩展来测试JPA类型转换器。 因此,我们注入了EntityManager并使用了@ShouldMatchData@UsingDataSet批注来验证数据库并使用yml文件设置种子。

如果您想自己尝试,可以在github上找到源代码。
您可以通过调用以下命令来运行它:git clone https://github.com/thjanssen/JPA2.1.git && cd JPA2.1 / CryptoConverter && mvn测试。

使用Arquillian测试Java EE应用程序有什么经验? 请对此发表评论。
想要了解有关Arquillian的更多信息,请参阅Arquillian Guides: http ://arquillian.org/guides/

翻译自: https://www.javacodegeeks.com/2014/06/testing-with-aliens-how-to-test-a-jpa-type-converter-with-arquillian.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363445.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

关于 C语言的 按位取反 ~

1、相关概念&#xff1a; 不管是正整数 还是 负整数在计算机中都是以 补码的形式存在的&#xff1b; 取反&#xff1a;0变1&#xff0c;1变0 就叫做取反&#xff0c;取反 符号位也要改变&#xff1b; 反码&#xff1a;符号位不变&#xff0c;其他位置0变1&#xff0c;1变0&a…

英语句型之展现问题篇3

表达不确定的用词&#xff1a;May, seem, be likely to, possible, probably, perhaps, be said that, be said to...51. In my mind, the following factors/reasons/causes need to be taken into consideration我认为&#xff0c;我们需要考虑下列因素/原因&#xff1a;52. …

【noip模拟赛5】任务分配 降维dp

描述 现有n个任务,要交给A和B完成。每个任务给A或给B完成&#xff0c;所需的时间分别为ai和bi。问他们完成所有的任务至少要多少时间。 输入 第一行一个正整数n&#xff0c;表示有n个任务。接下来有n行&#xff0c;每行两个正整数ai&#xff0c;bi。 输出 一个数&#xff0c;他…

解决win7下无法安装突击者NO.69驱动,“WINDOWS已找到设备的驱动程序,但在试图安装它时错误”...

本人装的是win7旗舰版&#xff0c;由于是ghost安装的&#xff0c;缺少一些文件&#xff0c;之前一直无法正确安装突击者电子狗的驱动程序&#xff0c;老是显示“WINDOWS已找到设备的驱动程序&#xff0c;但在试图安装它时错误”&#xff0c;baidu、google了几天都没解决&#x…

C语言 按位或 正整数与负整数 之间

按位或&#xff1a; 两个位 比对时&#xff0c;如果有一个位 为1&#xff0c;结果就为1&#xff1b; 按位或 时 &#xff0c;都是 按照补码来比对的 &#xff0c;正数的补码 是 本身&#xff0c;负数的补码 不是本身 所以 正负数按位或 要注意&#xff1a; 举例子&#xff1a;…

使用自定义日志记录处理程序在JBoss AS 7中跟踪SQL语句

使用ORM从您的特定数据库中提取数据&#xff0c;并让它创建和发布您必须亲自编写的所有SQL语句似乎很方便。 这就是使ORM解决方案受欢迎的原因。 但是它也有一个缺点&#xff1a;由于ORM为您做了很多工作&#xff0c;因此您在某种程度上失去了对生成的SQL的控制&#xff0c;您…

C语言 >> 右移位运算符的原理和一些概念

1、右移位于左移位不同 左移位 不管是 逻辑移位 算术移位 都是低位补0&#xff1b; 右移位 的 逻辑移位和算术移位不同&#xff0c; 算术移位高位补符号位&#xff0c;逻辑移位 高位补0&#xff1b; 右移位 使用逻辑移位的话 需要强制转换成unsigned 无符号型&#xff1b; 2…

去除git版本控制

命令&#xff1a;find . -name ".git" | xargs rm –Rflinux $ find . -type d -iname __pycache__ -exec rm -rf {} \;转载于:https://www.cnblogs.com/gispathfinder/p/10555347.html

PHP基础语法6

//PHP循环语句//for循环for ($i 0; $i < 18; $i) {echo $i . <br>;}//while循环$l 0;while ($l < 18) {echo $l . <br>;$l;}//foreache()用于数组循环的语句$arr [a > 1, b > 2];foreach ($arr as $key > $value) {echo $key . . $value . <…

如何在Java中找到整数的质因数–因式分解

编程课程中的常见家庭作业/任务之一是关于Prime Factorization。 要求您编写一个程序以找到给定整数的素因子 。 一个数字的质数因子是将精确地除以给定数字的所有质数。 例如&#xff0c;35的素数因子分别是7和5&#xff0c;它们本身都是素数&#xff0c;并且精确地除以35。上…

Arduino Serial系列函数 有关print read 的总结

总结一下 在学习arduino srial函数时 的几个知识点&#xff1a; /*** 汇总一下Serial.print输出的一些情况&#xff0c;后面部分要和Serial.read配合使用&#xff1b;* 1. print 输出字符 和int数的结果&#xff0c;* 2. print 输出字符串和一连串的数字* 3. read 读取一个字符…

C#经典名著:《C#入门经典》(第4版)

博客园专题&#xff1a;http://book.cnblogs.com/zt/begin_csharp/ 作  者&#xff1a; &#xff08;美&#xff09;沃森&#xff08;Watson&#xff0c;K.&#xff09;&#xff0c;&#xff08;美&#xff09;内格尔&#xff08;Nagel&#xff0c;C.&#xff09; 等著&#…

inheritPrototypal.js

// 原型式继承// 其基本思路是借助原型可以基于已有的对象创建新的对象function object(o){function F(){}F.prototype o;return new F();}var person {name: "Tom",friends: ["Jack", "John", "Kim"]};var David object(person);…

vue 用户输入搜索 与无限下拉

vue项目中,用户输入关键字搜索,并且手机端做无限下拉 watch: {getListForm.searchKey(val) { this.radioChange(); // 还有其他逻辑,内部调用getDeviceList}} 1 getDeviceList() {2 apiGetDeviceList(Qs.stringify(this.getListForm)).then(res > {3 …

您必须学习Java 8的函数式编程吗?

我最近一直在研究Java 8&#xff0c;并掌握了Manning出版的“ Java 8 In Action” 。 让我印象深刻的第一件事是Java 8的独特销售主张是函数式编程。 函数现在是一流的变量&#xff0c;您可以像int或String一样在代码中传递它们。 这是一个很大的变化。 近年来&#xff0c;功能…

鞋扔布什游戏

布什同学立功了&#xff01;&#xff01;在经济如此不景气的情况下&#xff0c;布什给全世界人民增加了一点笑料&#xff0c;多么伟大的奉献精神。 前几天就看到一个Flash游戏&#xff0c;不过那个是扮演保镖&#xff0c;用枪打掉扔向布什的鞋子&#xff0c;很不爽&#xff0c;…

Arduino 软串口通信 的几点体会

1、arduino主板上的 RX TX 引脚 有时不一定够用&#xff0c;这时就需要将别的 引脚 通过软件 模拟成串口通信引脚&#xff0c;但不是每个引脚 都能这么转换&#xff0c;不同的板子&#xff0c;有所不同。 2、arduino Uno 上只有一个 RX TX 引脚&#xff0c;分别是 0和1 引脚…

coffee.js

()( () )( ( () ) )########################################################################### ##################### ################### ##################################### 更多专业前端知识&#xff0c;请上 【…

巨蟒django之权限6: 权限控制表设计登录权限

1.权限控制表设计 内容 1. 什么是权限&#xff1f; 2. 为什么要有权限&#xff1f;不同用户拥有不同的功能 3. 在web开发中&#xff0c;什么是权限&#xff1f;url 代表 权限4. 开发一个权限的组件&#xff0c;为什么要开发组件&#xff1f;5. 表结构的设计# 第一版权限表 pe…

AJAX Tookits -- ConfirmButton

在AJAX Toolkits中有个ConfirmButton的扩展控件&#xff0c;该控件只能应用与Button类型的控件&#xff0c;例如Button和LinkButton。 当你点击按键之后&#xff0c;系统会弹出一个确认框。基本属性如下&#xff1a; TargetControlID - Button或Link的控件编号.ConfirmText - 弹…