[英]Unit testing private fields
我有一个简单的类,其中包含一个列表:
public class SomeClass {
private AppDataSource appDataSource; // it's interface
private List<Object> someList;
////
public List<Obejct> loadSomeList() {
if (someList == null) {
return appDataSource.getListFromDatabase();
}
retrunf someList;
}
}
关键是-我希望该列表仅从DB加载一次。 我想对该功能进行单元测试。 我在TDD中是菜鸟,我能做的就是-为someList编写一个公共的getter和setter方法,并在单元测试中使用它们。 但这在概念上是错误的-我不希望类的客户端直接使用此成员变量。
在这种情况下如何正确测试方法?
您正在错误进行单元测试。
单元测试是关于测试类的行为 。 没有实施细节。
您不测试私有字段是否具有此内容。 您测试的唯一一件事是方法执行了应做的事情。
当然,这意味着您的班级必须具有插入“特殊列表”进行测试的方法。
长话短说:您想退后一步,并花了接下来的2、3个小时来学习如何编写“易于测试的代码”; 例如,通过CleanCode观看Google Tech的精彩视频。
您应该在测试之前模拟列表。使用@Before初始化列表。
private List<Object> someList;
@Before
public void initialize() {
someList = new ArrayList<Object>();
someLisi.add(..);
someList.add(..);
}
并使用此模拟列表测试您的方法。您还可以使用@BeforeClass模拟列表。 您可以在此处阅读@Before和@BeforeClass之间的区别
您可以通过测试夹具中的构造函数来初始化私有字段。 我猜这是最普通的方式。
另一个选择是用Groovy编写测试,该测试可以直接访问Java类中的私有字段。 因此,您无需授予对私有字段的访问权限。
您可以像这样测试您的loadSomeList()
:
public class SomeClass {
private List<Object> someList;
public List<Object> loadSomeList() {
if (someList == null) {
someList = new ArrayList<>();
someList.add(new Object());
return someList;
}
return someList;
}
public List<Object> getSomeList() {
return someList;
}
public void setSomeList(List<Object> someList) {
this.someList = someList;
}
测试类应该有两个测试:
someClass.loadSomeList()
方法。 如果列表不为空,则表示测试通过。 someClass
实例是否已经具有列表。 在测试中,您只需在列表中添加一个对象并将其设置为someClass
。 public class SomeClassTest {
@Test
public void testLoadSomeListNewList() {
SomeClass someClass = new SomeClass();
List<Object> list = someClass.loadSomeList();
assertNotNull(list);
}
@Test
public void testLoadSomeListGivenList() {
SomeClass someClass = new SomeClass();
List<Object> list = new ArrayList<>();
list.add(new Object());
someClass.setSomeList(list);
someClass.loadSomeList();
assertTrue(someClass.getSomeList().size() == 1);
}
如果您在测试目录中创建的包与该类的包的名称相同,并且将该字段置于受保护的位置,则可以直接访问该字段
无需公开和测试列表,而是更改appDataSource以便可以从类外部进行设置。 使它成为提供getListFromDatabase()方法的接口。 然后进行测试,传入一个实现接口的模拟数据源,该数据源具有一个计数器,您可以查询该计数器以告知您调用了getListFromDatabase方法的次数。
查看您要测试的内容,然后再进行测试。 您没有在标准中提到列表本身很重要。 重要的是查询数据库的次数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.