使用Mockito spy继承ArrayBlockingQueue的类时遇空指针异常求助
解决Mockito Spy继承ArrayBlockingQueue类时的lock空指针问题
问题原因
当使用Mockito spy继承自ArrayBlockingQueue的类时,由于ArrayBlockingQueue的核心字段(如lock)是private final修饰,结合Java 18的模块访问限制,Mockito的ByteBuddy代理机制无法正确保留原实例的父类字段状态,导致调用put方法时出现this.lock空指针异常。
解决方案
1. 添加VM参数放宽模块访问限制
在测试运行时添加以下VM参数,允许Mockito访问java.util.concurrent包的内部成员:
--add-opens java.base/java.util.concurrent=ALL-UNNAMED
该参数解决了Java 9+模块系统对反射访问的限制,让Mockito能正确处理父类的final字段。
2. 手动实现测试子类替代Mockito Spy
如果不想依赖Mockito的spy机制,可编写测试专用子类,重写需要验证的方法来记录调用:
// 测试专用子类 class TestableMyBufferQueue extends MyBufferQueue { public int retryAllCallCount = 0; public TestableMyBufferQueue(int capacity) { super(capacity); } @Override public void retryAll() { retryAllCallCount++; // 若需保留原方法逻辑,添加:super.retryAll(); } } // 测试方法 @Test void testMyBuffer() { TestableMyBufferQueue queue = new TestableMyBufferQueue(1); queue.consumeFullQueue(); assertEquals(1, queue.retryAllCallCount); }
这种方式完全避开了Mockito的代理问题,逻辑直观,不会触发并发容器的字段访问异常。
3. 升级Mockito版本
将Mockito版本升级到最新稳定版(如4.11.0及以上),新版本可能修复了Java 18下与并发容器相关的代理兼容问题。
内容的提问来源于stack exchange,提问作者user3419082
相关产品推荐
相关产品推荐

