【发布时间】:2011-02-18 11:13:43
【问题描述】:
我有一段代码大致相当于下面的代码。
public class ConcreteThread extends OtherThread {
private DAOfirst firstDAO;
private DAOsecond secondDAO;
private TransformService transformService;
private NetworkService networkService;
public ConcreteThread(DAOfirst first, DAOsecond second, TransformService service1,
NetworkService service2) {
firstDAO = first;
secondDAO = second;
transformService = service1;
networkService = service2;
}
public Future go() {
Results r1 = firstDAO.getResults();
MyCallable c1 = new MyCallable(r1);
return super.getThreadPool().submit(c1);
}
private class MyCallable implements Callable {
private Results result;
private Long count;
private MyCallable(Results r) {
this.result = r;
this.count = new Long(0);
}
public Long call() {
Singleton transactions = Singleton.getInstance();
try {
transactions.begin();
while(result != null) {
Transformed t = transformService.transform(r1);
networkService.sendSomewhere(t);
count = count += result.size();
secondDao.persist(result);
result = firstDao.getNext(result);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
transactions.end();
}
}
}
这些类(内部或外部)都没有单元测试,结果发现内部类MyCallable 有一个错误。在我上面给你的代码的简化版本中,这个错误不存在。
因此,假设您决定修复错误,并为MyCallable 实施一些单元测试。我的问题是这个;您将如何为MyCallable 内部类编写单元测试?
我自己的解决方案是首先重构MyCallable 和ConcreteThread。 MyCallable 在其自己的文件中成为公共类,ConcreteThread 现在将 DAO、Services 和 Singleton 作为构造函数参数传递给 MyCallable,而不是依赖于内部类对其私有变量的访问。
然后我在单元测试中大量使用 EasyMock 来模拟这些依赖项并验证它们是否以我预期的方式被调用。
所有这一切的结果是MyCallable 的代码比原来要大一些。由于它不再能够访问ConcreteThread 中的私有变量,ConcreteThread 必须将它们作为参数传入构造函数,而MyCallable 将它们设置为私有变量。
您认为这是错误的方法吗?也许通过执行这种重构,我破坏了封装并在代码库中添加了不必要的样板?你会在测试中使用反射吗?
【问题讨论】:
标签: java unit-testing reflection encapsulation easymock