如何在由 spring 关闭的可自动关闭 bean 的单元测试中覆盖关闭方法
How to cover close method in unit tests for autocloseable beans closed by spring
我有几个 Spring beans/components 实现 AutoCloseable
,我希望 Spring 容器在应用程序上下文被销毁时关闭它们。
无论如何,我的代码覆盖工具在抱怨,因为从它的角度来看 close()
方法是 "uncovered by tests"。
我该怎么办:
- 引入一些简单的 close() 测试?
- 随它去吧,接受它们会降低覆盖率 %
- 还有别的吗?
您不是在测试应用程序关闭 bean,而是在测试 bean 在关闭时是否正确关闭。如果实现非常重要,那么您应该为该行为编写一个测试。如果您的方法所做的只是在单个字段上调用 close,那么请不要费心测试它。但是,如果您的 close 方法在多个字段上调用 close 或做一些更复杂的事情,那么您应该对其进行测试。
例如,假设以下 Closer
class 在关闭时必须关闭其所有 Reader
s...
public class Closer implements AutoCloseable {
private Reader[] readers;
public Closer(Reader... readers) {
this.readers = readers;
}
@Override
public void close() {
try {
for (Reader reader : readers) {
reader.close();
}
} catch (IOException ex) {
// ignore
}
}
}
您不妨这样测试:
public class CloserTest {
@Test
public void allReadersClosedWhenOneReaderThrowsException() {
// given
Reader badReader = mock(Reader.class);
Reader secondReader = mock(Reader.class);
doThrow(new IOException()).when(badReader).close();
Closer closer = new Closer(badReader, secondReader);
// when
closer.close();
// then
verify(badReader).close();
verify(secondReader).close(); // fails as loop stops on first exception
}
}
过高的代码覆盖率可能是一件坏事,如果这意味着您的单元测试包含大量琐碎的测试,尤其是当这些测试很脆弱时。他们将增加维护单元测试所需的工作量,而实际上并没有添加任何东西。
我有几个 Spring beans/components 实现 AutoCloseable
,我希望 Spring 容器在应用程序上下文被销毁时关闭它们。
无论如何,我的代码覆盖工具在抱怨,因为从它的角度来看 close()
方法是 "uncovered by tests"。
我该怎么办:
- 引入一些简单的 close() 测试?
- 随它去吧,接受它们会降低覆盖率 %
- 还有别的吗?
您不是在测试应用程序关闭 bean,而是在测试 bean 在关闭时是否正确关闭。如果实现非常重要,那么您应该为该行为编写一个测试。如果您的方法所做的只是在单个字段上调用 close,那么请不要费心测试它。但是,如果您的 close 方法在多个字段上调用 close 或做一些更复杂的事情,那么您应该对其进行测试。
例如,假设以下 Closer
class 在关闭时必须关闭其所有 Reader
s...
public class Closer implements AutoCloseable {
private Reader[] readers;
public Closer(Reader... readers) {
this.readers = readers;
}
@Override
public void close() {
try {
for (Reader reader : readers) {
reader.close();
}
} catch (IOException ex) {
// ignore
}
}
}
您不妨这样测试:
public class CloserTest {
@Test
public void allReadersClosedWhenOneReaderThrowsException() {
// given
Reader badReader = mock(Reader.class);
Reader secondReader = mock(Reader.class);
doThrow(new IOException()).when(badReader).close();
Closer closer = new Closer(badReader, secondReader);
// when
closer.close();
// then
verify(badReader).close();
verify(secondReader).close(); // fails as loop stops on first exception
}
}
过高的代码覆盖率可能是一件坏事,如果这意味着您的单元测试包含大量琐碎的测试,尤其是当这些测试很脆弱时。他们将增加维护单元测试所需的工作量,而实际上并没有添加任何东西。