You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Mockito创建的Mock调用Getter时未用构造函数值,原因何在?

问题原因及解决办法

为什么Mock对象的getPrice()不返回18.99?

Mockito用@Mock创建的是完全模拟的代理对象,它不会执行原Football类的任何构造逻辑,也不会保留原类的字段和方法实现:

  • 原类构造函数里硬编码的18.99是传给父类的,但Mock对象根本不会调用这个构造方法;
  • getPrice()方法在Mock对象里被替换成了Mockito的默认实现,对于Double类型的返回值,默认返回null,自然不会得到你想要的18.99。

另外提一句:你原Football类的逻辑有个小矛盾——构造函数给父类传的是18.99,但自己的getPrice()返回的是构造参数里的price,这俩本来就不是同一个值,就算用真实对象,getPrice()也不会返回18.99,而是返回你构造时传入的price参数。

怎么解决?

根据你的测试需求选对应的方式:

1. 直接创建真实对象(测试POJO自身逻辑用)

如果你的测试就是要验证Football的自身逻辑,完全没必要用Mock,直接new实例就行:

Football football = new Football(Colour.RED, 20.0);
// 此时getPrice()返回的是传入的20.0,父类的价格是18.99

2. 用@Spy做部分模拟(需要保留原类部分方法逻辑)

如果你需要模拟Football的某些方法,但想保留getPrice()的原逻辑,用@Spy代替@Mock,而且必须显式调用构造函数初始化:

@Spy
Football football = new Football(Colour.BLUE, 15.0);

@BeforeEach
private void initMocks() {
    MockitoAnnotations.openMocks(this);
}

这时调用getPrice()会执行原方法,返回构造时传入的15.0。

3. 给Mock对象指定返回值(必须用Mock的情况)

如果一定要用@Mock,可以通过Mockito指定getPrice()的返回值:

@Mock
Football football;

@BeforeEach
private void initMocks() {
    MockitoAnnotations.openMocks(this);
    when(football.getPrice()).thenReturn(18.99);
}

这样调用football.getPrice()就会返回你期望的18.99。

内容的提问来源于stack exchange,提问作者java12399900

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 07:22:53