使用Specs2 Mockito模拟返回int的方法时触发空指针异常求助
问题根源
这个NullPointerException的核心原因是基本类型拆箱时的空指针异常:Calculator.calculate方法返回基本类型int,但Mockito内部拦截逻辑返回了null,而null无法自动拆箱为int,触发了Cannot invoke "java.lang.Integer.intValue()"错误。
结合你的环境与代码,主要有两个触发因素:
- Mockito版本与Java 17不兼容:你使用的
specs2-mock:4.13.3依赖Mockito 3.x版本,而Mockito 3.x对Java 17的反射模块限制和字节码生成逻辑支持不完善,导致处理基本类型返回值时出现异常。 - 被Mock类的构造函数依赖干扰:
Calculator类的构造函数需要Int参数,创建mock时,Mockito可能因构造函数调用引发的内部逻辑问题,导致方法拦截时返回值处理失败。
解决方案
方案一:升级Specs2到兼容Java 17的版本
将specs2相关依赖升级到支持Java 17的最新稳定版,该版本依赖的Mockito 4.x完全适配Java 17:
libraryDependencies ++= Seq( "org.specs2" %% "specs2-core" % "4.19.0" % Test, "org.specs2" %% "specs2-mock" % "4.19.0" % Test )
方案二:显式指定返回值的包装类型
如果暂时无法升级版本,可以通过显式指定包装类型避免拆箱空指针:
// 用willReturn替代returns,或显式转为Integer f.calculate(any[Pair]) willReturn Integer.valueOf(6) // 或者 f.calculate(any[Pair]) returns 6: Integer
方案三:配置Mock的默认返回策略
创建mock时指定RETURNS_SMART_NULLS策略,该策略会为基本类型返回默认值(如int返回0),避免空指针:
val f = mock[Calculator](Mockito.withSettings().defaultAnswer(Answers.RETURNS_SMART_NULLS))
验证示例
升级版本后,原测试代码即可正常运行,示例如下:
import org.specs2.matcher.ShouldThrownExpectations import org.specs2.mock.Mockito import org.specs2.mutable.Specification import org.specs2.specification.Scope class DemoTest extends Specification { isolated "Demo.run" should { "return 11 when calculate returns 6" in new Mocks { f.calculate(any[Pair]) returns 6 val res = demo.run(Pair(1,"str")) res shouldEqual 11 } } } trait Mocks extends Scope with Mockito with ShouldThrownExpectations{ val f = mock[Calculator] val demo = new Demo(f) }
内容的提问来源于stack exchange,提问作者Shashi
相关产品推荐
相关产品推荐

