【发布时间】:2012-01-11 23:39:33
【问题描述】:
我正在寻找一种方法来测试某个给定的 List 是否是不可修改的。
我有一个具有List<NoMatter> 的对象,为了提供诸如addNoMatter(NoMatter nm) 之类的方法,而不是允许API 客户端简单地执行.getNoMatters().add(nm); 我总是返回此列表的不可修改版本,因此客户端是仍然能够拥有列表。我这样做如下:
public List<NoMatter> getNoMatters() {
return Collections.unmodifiableList(this.noMatters);
}
问题是,当我进行测试时,我根本无法检查此对象是否属于 UnmodifiableList 类型。我的第一次尝试是:
@Test
public void checkIfListIsImmutable(){
assertTrue("List is not immutable", this.myObj.getNoMatters() instanceof UnmodifiableList);
}
我似乎无法导入UnmodifiableList 和java.util.Collections$UnmodifiableRandomAccessList 类型,这就是我在控制台上尝试System.out.println(myObj.getNoMatters().getClass().getName()); 时得到的结果。
那我该如何实现呢???
PS.:我知道我可以通过以下测试:
@Test(expected = UnsupportedOperationException.class)
public void checkIfListIsImmutable(){
this.myObj.getNoMatters().add(null);
}
编辑: 上面的测试并没有让我知道我处理的列表不是不可变的,因为我需要对每个可能修改我的原始列表的方法进行测试,包括 .remove ()、.clear()、.shuffle() 等!这就是为什么我认为这不是一个很好的方法。
>>> 但我仍然相信它甚至没有接近一个优雅的解决方案!
【问题讨论】:
-
我建议使用“addAll(Collections.emptyList());”而不是 add(null) 来测试不可变。如果不可变,这将引发 UnsupportedOperationException,如果可变则不会修改列表。我同意修改列表以查看它是否是不可变的感觉不对,并且如果其他人使用该列表可能会导致问题。
-
@SteveZobell 的建议就像蛋糕上的樱桃。解决了 List 实际上是可变的问题。需要考虑的一件事是 UnmodifiableList 不是 Java API 中唯一的不可修改列表。 Collections.nCopies(..) 返回一个 Collections$CopiesList 的实例,该实例也是不可修改的。从 AbstractList 实现一个不可修改的列表非常容易,因此最好的办法是测试其行为。
标签: java unit-testing collections tdd