我有一段代码大致等同于以下代码。

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内部类编写单元测试?

我自己的解决方案是首先重构MyCallableConcreteThreadMyCallable在其自己的文件中成为公共类,并且ConcreteThread现在将DAO,服务和Singleton传递为MyCallable的构造函数参数,而不是依赖内部类对其私有变量的访问。

然后,我在单元测试中大量使用EasyMock来模拟那些依赖关系,并验证它们是否按照我期望的方式被调用。

所有这些的结果是MyCallable的代码比以前更大。由于它不再有权访问ConcreteThread中的私有变量,因此ConcreteThread必须将它们作为构造函数中的参数传递,并且MyCallable将它们设置为私有变量。

您是否认为这是错误的方法?也许通过执行这种重构,我破坏了封装并在代码库中添加了不必要的样板?您会在测试中使用反射吗?

最佳答案

所有这些的结果是MyCallable的代码比以前更大。由于它不再有权访问ConcreteThread中的私有变量,因此ConcreteThread必须将其作为构造函数中的参数传递,而MyCallable会将其设置为私有变量。


这是一个很好的结果,MyCallable不再依赖于ConcreteThread的更改。

我认为问题和答案是相当主观的,但是我认为您在重构中遵循了SOLID原则(这是一件好事)。

并且如果可以的话,请保护MyCallable程序包,而不是公开:)

关于java - 重构测试,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5040588/

10-11 09:13