要测试自定义资源在 try-with-resources 中是否被正确关闭,需验证 close() 方法被调用且仅一次:1. 资源须实现 AutoCloseable;2. 正常执行时 close 被调用;3. try 块抛异常时 close 仍被调用;4. 可用 Mockito 验证调用次数。

要测试自定义资源在 try-with-resources 中是否被正确关闭,核心是验证 close() 方法是否被调用,且只调用一次,无论 try 块中是否抛出异常。
确保资源实现 AutoCloseable 接口
这是前提。自定义类必须实现 AutoCloseable,并重写 close() 方法:
public class TestResource implements AutoCloseable {
private boolean closed = false;
@Override
public void close() {
if (closed) {
throw new IllegalStateException("Already closed");
}
closed = true;
}
public boolean isClosed() {
return closed;
}
}
用普通 try-with-resources 语句触发关闭
编写最简测试用例,覆盖正常执行路径:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 创建资源实例
- 在 try-with-resources 中使用它(哪怕只写个空语句)
- 结束后断言
isClosed()返回true
@Test
void testCloseIsCalledOnNormalExecution() {
TestResource resource = new TestResource();
try (resource) {
// do nothing
}
assertTrue(resource.isClosed());
}
测试异常场景下的关闭行为
try-with-resources 要求即使 try 块抛出异常,close() 也必须执行。可模拟两种情况:
立即学习“Java免费学习笔记(深入)”;
- try 块抛异常,close 不抛异常:验证资源仍被关闭
-
try 块和 close 都抛异常:验证 try 块异常为主异常,close 异常被抑制(可通过
getSuppressed()检查)
@Test
void testCloseIsCalledWhenTryThrows() {
TestResource resource = new TestResource();
assertThrows<RuntimeException>(() -> {
try (resource) {
throw new RuntimeException("from try");
}
});
assertTrue(resource.isClosed());
}
用 Mockito 或手动打桩验证 close 调用次数
避免依赖状态字段(如 isClosed),更直接的方式是验证 close() 是否被调用,尤其适合已有复杂逻辑的资源类:
- 用 Mockito 模拟资源(需是接口或有无参构造),或使用
spy包裹真实对象 - 在 try-with-resources 后检查
verify(mock).close() - 可加
times(1)明确要求只调用一次
@Test
void testCloseIsCalledExactlyOnce() {
TestResource spy = spy(new TestResource());
try (spy) {
// do something
}
verify(spy, times(1)).close();
}

















