JUnit增强工具及JUnit3与JUnit4的差异解析
立即解锁
发布时间: 2025-08-18 02:07:15 阅读量: 4 订阅数: 10 

JUnit 4.8实战:提升软件质量的关键工具
### JUnit增强工具及JUnit 3与JUnit 4的差异解析
#### 1. JUnit增强工具
##### 1.1 JUnit-addons
JUnit-addons 的 `PrivateAccessor` 类提供了与之前手动实现的方法类似的功能。不同之处在于方法名(`getField()` 和 `setField()`,而非 `get()` 和 `set()`)、实现方式(使用 `for` 而非 `while`),并且 `getField()` 不返回参数化的值(因为 JUnit-addons 早于 Java 5)。
直接使用 `PrivateAccessor` 时,可将 `setFixtures()` 中的 `set DAO` 语句重写为:
```java
PrivateAccessor.setField(facade, "userDao", dao);
```
不过,直接使用 `PrivateAccessor` 存在三个缺点:
- `getField()` 不是参数化的,因此在每个测试用例中都需要对其返回值进行强制类型转换。
- 调用者必须检查 `NoSuchFieldException`。
- 所有测试用例都需要直接依赖第三方工具,这会使后续切换到其他工具更加困难。
更好的方法是在 `TestingHelper` 方法中间接使用 `PrivateAccessor`,而不是在测试用例本身中使用,如下所示:
```java
import junitx.util.PrivateAccessor;
public class TestingHelperJUnitAddons {
public static void set( Object object, String fieldName,
Object newValue ) {
try {
PrivateAccessor.setField(object, fieldName, newValue);
} catch (Exception e) {
throw new RuntimeException( "Could not set value of field '" +
fieldName + "' on object " + object + " to " + newValue, e );
}
}
public static <T> T get(Object object, String fieldName) {
try {
Object value = PrivateAccessor.getField(object, fieldName);
@SuppressWarnings("unchecked")
T castValue = (T) value;
return castValue;
} catch (NoSuchFieldException e) {
throw new RuntimeException( "Could not get value of field '" +
fieldName + "' from object " + object, e );
}
}
}
```
`PrivateAccessor` 还提供了其他一些方法,如 `invoke()`(用于调用任何实例或静态方法),以及处理静态方法的 `getField()` 和 `setField()` 的重载版本。
##### 1.2 FEST-Reflect
FEST-Reflect 提供了辅助类来访问各种 Java 实体,如字段、方法、构造函数,甚至内部类。与所有其他 FEST 模块一样,它采用流畅接口方法,这次使用 `org.reflect.core.Reflection` 作为入口点。
例如,要创建一个 `User` 对象的实例,可以使用 `constructor()` 方法:
```java
User user = Reflection.constructor().in(User.class).newInstance();
```
在幕后,`constructor()` 返回一个 `TargetType` 对象,其 `in()` 方法返回一个 `Invoker`,该 `Invoker` 又通过 `newInstance()` 方法创建实际的 `User` 实例。所有这些方法都使用参数化参数和返回值(类似于清单 19.9 中的 `get()` 方法),因此结果可以直接使用,无需显式强制类型转换。
不过,大多数情况下,必须在调用链的某个位置将预期的类作为参数传递。例如,要使用 FEST 设置 DAO,必须明确指出该字段是 `UserDao` 类型:
```java
Reflection.field("userDao").ofType(UserDao.class).in(facade).set(dao);
```
由于这些要求,如果不更改 `TestingHelper` 的签名以包含字段类,则无法使用 FEST 重写它,这也需要更改 `set DAO` 语句:
```java
TestingHelperFESTReflect.set(facade, "userDao", UserDao.class, dao);
```
以下是重构后的 `TestingHelper` 类:
```java
import org.fest.reflect.core.Reflection;
public class TestingHelperFESTReflect {
public static <T> void set(Object object, String fieldName,
Class<T> fieldClass, T newValue) {
Reflection.field(fieldName).ofType(fieldClass).in(object).set(newValue);
}
public st
```
0
0
复制全文


