Unitils 使用指南
单元测试起码理论上应该简单和直观的,但是真实生活中的项目通常涉及很多方面,例如数据驱动和中间件技术的使用,例如EJB和hibernate.
Unitils 起初希望在测试中能找到一个比较实际的视角来解决问题。它开始有一套自己的指导原则并且有了一个开源的库包含一些工具,这些工具使遵循了这些原则的应用便的容易测试。
这个使用指南将给你展示一些例子,来掩饰Unitils可以对你的项目做什么。如果你想学习怎么配置Unitils 来快速上手,你可以读我们的cookbook.
-
断言工具
-
Unitils
模块
-
数据库测试
-
自动测试数据维护
-
使用hibernate的程序测试
-
使用JPA的应用测试
-
使用Spring的应用的测试
-
使用Mock对象的应用的测试
-
对EasyMock的支持
-
1
断言工具
我们开始这个想到通过描述一些断言工具,他可以在Unitils核心模块系统之外独立使用,这这个文档的附件里会描述这些。不需要配置,只需要增加Unitils包和核心依赖到你项目的classpath既可以在你的单元测试里使用它了。
2 为断言使用反射
一个典型的单元测试通常包含对希望值和实际值的比较。Unitils提供断言工具抱住你做这件事情。让我们开始一个比较两个用户实例的例子,这个用户实例包含用户id,first 和last name.
public class User {
private long id;
private String first;
private String last;
public User(long id, String first, String last) {
this.id = id;
this.first = first;
this.last = last;
}
}
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertEquals(user1, user2);
你可能期望这个断言是成功的,因为两个实例包含合理相同的值,然而不是这种情况,因为User对象没有重写equals方法,检查两个User实例的相等其实是检查两个对象是否为同一个对象。换句话说上面的验证将会返回fail.
加入你实现了如下的相等方法:
public boolean equals(Object object) {
if (object instanceof User) {
return id == ((User) object).id;
}
return false;
}
这是一个合理的实现符合你的应用逻辑,通过两个用户实例是否有相同的idl来比较他们是否相等。然而这个方法对你的单元测试是没用的。测试是否两个对象相等便成了测试他们是否拥有相同的id了。
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "Jane", "Smith");
assertEquals(user1, user2);
这个断言将是成功的,但可能不是你想要的。最好的是避免使用equals()当你比较对象的时候(当然除了表达值的对象,如java.lang.String?)。你也可以比较每一个属性:
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertEquals(user1.getId(), user2.getId());
assertEquals(user1.getFirst(), user2.getFirst());
assertEquals(user1.getLast(), user2.getLast());
Unitils提供了更容易的方式来检查这些属性,就是通过映射。
使用 ReflectionAssert.assertReflectionEquals,上面的例子可以被改写成这样:
User user1 = new User(1, "John", "Doe");
User user2 = new User(1, "John", "Doe");
assertReflectionEquals(user1, user2);
这个断言通过反射来循环比两个对象的所有的属性值,对上面的例子,他会以此比较id值,first值和last值。
如果一个属性自己也是一个对象,它将递归的去比较这个对象的属性值。对collections,maps,arrays类型也是一样。他们的元素将被贯穿的递归的通过反射来比较。如果一个值是基本类型或者基本封装类型,他们将会通过值的是否相同来比较。结果是下面的断言将返回成功。
assertReflectionEquals(1, 1L);
List<Double> myList = new ArrayList<Double>();
myList.add(1.0);
myList.add(2.0);
assertReflectionEquals(Arrays.asList(1, 2), myList);
3 宽容的断言
由于可维护性的远影,为测试仅仅添加值的断言是重要的。让我用一个例子说明一下原因:假设你有一个测试计算一个账户余额,那么任何检查这个银行账户的姓名则是没有必要的。这只会增加你测试的复杂度,而且变的不易理解,更重要的是如果代码改动很容易造成不好的影响。如果你想你的测试代码容易保留下来,在重构和代码变动的时候,那么请尽量制作必要的断言。
为了帮助你写断言,我们提供了一些反射断言检查的级别,后面会详细介绍。
4 不重要的次序
To implement this behavior, the ReflectionAssert.assertReflectionEquals method
can be configured to ignore ordering by supplying it theReflectionComparatorMode.LENIENT_ORDER comparator
mode:
List<Integer> myList = Arrays.asList(3, 2, 1);
assertReflectionEquals(Arrays.asList(1, 2, 3), myList, LENIENT_ORDER);
第一种可以容忍的情况你可能会想到集合类型(collection or array)中元素的次序.当使用这些集合类型,你经常不会关系元素的次序。例如遍历所有银行账户的负账户数代码会按照一定顺序返回这个集合,但是顺序在实际处理中并不重要。
5 忽略默认值
第二种类型的容忍模式可以通过 ReflectionComparatorMode.IGNORE_DEFAULTS 来设定。
配置这个模式以后,java默认值,像对对象的null,以及0,false都会被忽略。换句话说,只有那些属性被属性(在你期望对象中有意指定的属性)在你的对比中。
下面有个列子,假设你有一个用户类(first name,last name,street 等字段),你只希望检查结果的用户对象中是否有特定的firstname 和 street 值,而忽略其他属性值。
User actualUser = new User("John", "Doe", new Address("First street", "12", "Brussels"));
User expectedUser = new User("John", null, new Address("First street", null, null));
assertReflectionEquals(expectedUser, actualUser, IGNORE_DEFAULTS);
在断言语句中,第一个对象中,如果属性被设置为null ,那么它将在比较中被忽略。但是第二个参数中的null 值,仍会被比较,是不会被忽略的。
assertReflectionEquals(null, anyObject, IGNORE_DEFAULTS); // Succeeds
assertReflectionEquals(anyObject, null, IGNORE_DEFAULTS); // Fails
6 可以容忍的数据
另一种宽容的策略是通过ReflectionComparatorMode.LENIENT_DATES来设置。这样断言语句会判断实例中的属性是否都被设置了或者是否都等于null,而不在乎具体日期是什么值。这个特性是比较有用在你想对对象属性做严格检查的时候(没有使用ReflectionComparatorMode.IGNORE_DEFAULTS),但是你对象的属性使用了当前日期或者时间。
Date actualDate = new Date(44444);
Date expectedDate = new Date();
assertReflectionEquals(expectedDate, actualDate, LENIENT_DATES);
分享到:
相关推荐
为了避免这种情况,我们可以使用 Unitils 的断言方法,例如 ReflectionAssert.assertReflectionEquals 方法。 使用 ReflectionAssert.assertReflectionEquals 方法,可以循环比较两个对象的字段值,从而确保对象的...
综上所述,"使用Unitils测试DAO"的主题涵盖了如何利用Unitils库和DBUnit组件来创建可靠的DAO层测试,包括数据库的初始化、数据集的管理、断言的使用,以及自定义工具类的创建和源码分析。这种测试方法有助于提升代码...
- **背景**: 此指南适用于Postman应用程序(而非Chrome扩展),基于官方文档与实践经验编写。 - **目标**: 提供Postman使用技巧和常见问题解决方案。 - **内容结构**: - **Cheatsheet**:快速查阅表,包含常用命令...
在断言方面,Unitils提供了一套强大的断言工具,比如对于复杂的对象比较,它能方便地比较两个对象实例的所有属性,比如在示例中的User类,可以轻松地对比id、firstName和lastName属性,以确保测试结果的准确性。...
"Go-测试框架断言-基础的断言Go库"这个标题提到的库,很可能是一个辅助进行断言操作的第三方工具,类似于`assert`包。描述中提到的"Package assert is a Basic Assertion library used along side native go testing...
可以使用`store.commit()`方法触发mutation,然后使用断言验证`state`的变化。 3. **断言Actions**: `actions`用于处理异步操作,它们可以派发`mutations`来改变`state`。在测试中,我们需要模拟环境并调用`store....
断言可以在开发和测试阶段使用,以确保程序的正确性和可靠性。 Java断言的历史 Java断言是从 JDK 1.4 引入的,默认情况下是关闭的。断言可以在局部开启,但它不具备继承性,即父类可以禁止断言,而子类可以开启断言...
06_类型断言-联合类型-交叉类型
在配置路由断言工厂(Route Predicate Factories)和网关过滤器工厂(Gateway Filter Factories)时,可以使用简写或完全展开的方式。例如,在`application.yml`中,可以定义路由及其断言和过滤器,以控制请求如何被...
Cadence公司的断言验证手册是一份专注于基于SVA(System Verilog Assertions)的断言验证技术指南。SVA是一种在硬件设计和验证过程中使用的技术,用于通过形式化方法来验证数字电路的功能正确性。这份手册强调了使用...
Python中的断言是一种编程实践,用于确保...使用断言时,应确保在生产环境中谨慎处理,因为对于某些性能敏感的应用,过度使用断言可能会对程序性能产生影响。通常,断言主要用于开发和测试环境,而不是部署到生产环境。
这个概念在【标题】"Java中断言使用案例"中被强调,而【描述】进一步指出文档会探讨使用断言的优势及其用法。下面将详细阐述Java中断言的原理、好处以及如何使用。 1. **什么是Java断言**: Java断言是一种机制,...
- Postman将生成一段JavaScript代码,通过`pm.response.text()`获取响应体内容,并使用`pm.test`函数进行断言。 - 用户需在`response_body_string`处填入预期的完整响应体内容。 - 运行测试后,如果响应体与预期完全...
断言使用 `assert` 关键字,其基本语法如下: ```python assert condition, message ``` 在这里,`condition` 是一个布尔表达式,如果该表达式的值为 `False`,则会触发 `AssertionError` 异常。`message` 是一个...
本指南将详细介绍 SV assertation 的应用,包括断言的概念、断言的类型、断言的语法、断言的实现方法等。 断言的概念 ------------- 断言是设计的属性描述,用于监视设计的行为是否符合预期。如果设计的行为不符合...
本指南将深入介绍JUnit4.x的关键特性和使用方法,帮助开发者更好地理解和应用这个强大的测试库。 1. **JUnit4.x的基本概念** - 单元测试:单元测试是对软件中的最小可测试单元进行检查和验证,例如单个函数、方法...
jmeter3实现返回json串的断言,将 jmeter-plugins-json-2.3.jar 复制到lib/ext/.