为什么JUnit测试方法不能返回一个值?
文档说(强调我的):
测试方法和生命周期方法可以在当前测试类中本地声明、从超类继承或从接口继承(参见测试接口和默认方法)。此外,测试方法和生命周期方法不能是抽象的,也不能返回值。
为什么是这样强制的?
这纯粹是设计上的选择吗?这是最好的做法吗?
发布于 2020-03-12 13:11:34
这纯粹是设计上的选择吗?
是。理论上,没有什么可以阻止Junit运行程序(运行测试类测试的组件)接受具有返回值的测试方法的有效性。
这是最好的做法吗?
确实如此。您越限制指定单元测试方法的方式,就越能确保不会发生误用。
例如,看看这个简单的示例,它假设一个测试方法返回一个值。
一个addFoo()测试方法,它断言该方法执行预期的操作,并返回创建的Foo夹具:
@Test
public Foo addFoo(){
Foo foo = new Foo(...);
// call the api ...
sut.addFoo(foo);
// assertion
assertEquals(...);
// return the foo fixture
return foo;
}在这里,有一个addFooBar()测试方法,它检索由前一个方法创建的Foo夹具,然后断言方法addFooBar()完成了预期的任务:
@Test
public void addFooBar(){
Foo foo = addFoo();
Bar bar = new Bar(..., foo);
// call the api ...
sut.addFooBar(bar);
// assertion
assertEquals(...);
}这就产生了多个问题:
addFoo()应该多次执行吗?这可能会影响测试速度的执行,使测试报告不清晰。addFoo()测试结果可以使addFooBar()测试结果在正确的实现中失败。
如何诊断问题的根源?我们增加了无用的复杂性。addFoo()测试结果可以使addFooBar()测试结果在不正确的实现中成功。实际上,addFoo()中的不正确实现可以补偿addFooBar()中的不正确实现。发布于 2020-03-12 13:02:55
有一件事我还没见过,那就是这个设计决策背后的原因之一是历史性的。
在以注释为标记的测试用例之前,它们通过反射进行JUnit分析--所有public void方法(其名称以test开头,且没有任何参数)都被认为是由框架运行的测试用例。
如果允许这些方法也返回值,则不可能创建以test开头的公共助手方法,该方法计算某些测试中通常使用的值,否则框架运行程序将尝试运行它。
我想你应该把他们变成私密的。
此外,这也是“以动词开始的方法名应该做某事”(而不是计算某事)的高峰期。
发布于 2020-03-12 12:39:35
您可以编写一些私有方法并重用它们,例如
@Test
public void test1() {
privateTest();
}
@Test
public void test2() {
privateTest();
// more Logic
}
private int privateTest() {
return 0;
}https://stackoverflow.com/questions/60654124
复制相似问题