【发布时间】:2018-06-21 15:25:02
【问题描述】:
我有一个名为“foo”的函数,它产生一个字符串数组列表。 foo 总是返回一个大小为 2 的非空数组。当我尝试访问超出范围的元素时,我应该得到“IndexOutOfBounds”异常。测试方法有两种变体。第二个失败,而第一个工作正常。您认为导致第二个失败的原因是什么?
我尝试使用 assertThrows 检查异常,但没有按预期工作。
import java.util.ArrayList;
public class fooClass {
static ArrayList<String> foo (){
ArrayList<String> arrayOfSize2 = new ArrayList<String>();
arrayOfSize2.add("x");
arrayOfSize2.add("y");
return arrayOfSize2;
}
}
以下测试块正在工作
@Test
void testFoo() {
ArrayList<String> dummyArrayList = FooClass.foo();
assertEquals("x",dummyArrayList.get(0));
assertEquals("y",dummyArrayList.get(1));
assertThrows(IndexOutOfBoundsException.class, () -> dummyArrayList.get(2));
}
但是这个不行
@Test
void testFoo() {
ArrayList<String> dummyArrayList = new ArrayList<String>();
dummyArrayList=fooClass.foo();
assertEquals("x", dummyArrayList.get(0));
assertEquals("y", dummyArrayList.get(1));
assertThrows(IndexOutOfBoundsException.class, () -> dummyArrayList.get(2));
}
我希望第二个代码的 assertThrows 输出也是 True,但实际输出是 Local variable dummyArrayList defined in an enclosing scope must be final or effectively final
【问题讨论】:
-
您是说您在上面发布的代码中得到“必须是最终的或有效的最终”,还是您简化的更“复杂情况”?按照编码,它对我来说完美无缺,抛出异常,断言成功。
-
您刚刚发现了另一个需要解决的难题。似乎我在简化问题的同时偏离了目标。在原始代码中,我初始化了 dummyArrayList,然后分配了函数的返回值。我将通过添加一个完整的示例来改进帖子。
-
感谢您更新代码。实际上,Rahul B 是正确的(尽管他在发布时不知道),这里唯一的问题是 dummyArrayList 被分配了两次,然后在 lambda 中使用。我相信你可以看到第一行是没有用的,对吧?只需将这两行组合起来,就不会重新分配 dummyArrayList(这为您提供了工作测试方法),您会没事的。
-
感谢您的评论。我可以看到第二个测试块的第一行是没有意义的,但是由于我希望它具有最后一个分配的值,所以我不完全理解失败背后的原因。从我的角度来看:
ArrayList<String> dummyArrayList = FooClass.foo();等于ArrayList<String> dummyArrayList = new ArrayList<String>(); dummyArrayList=fooClass.foo(); -
Caglar,是的,它们是相同的,但是将其分配两次意味着 dummyArrayList 更改。为了使用在闭包外部声明的变量,它的引用不能改变。即使您知道这无关紧要(因为闭包将使用分配的第二个实例),Java 编译器也会拒绝,因为它要求它是“最终的或有效的最终”。
标签: unit-testing lambda exception-handling java-8 junit5