如何测试含@Resource注解Boolean字段的Java类?Mockito报错求助
解决Mockito无法mock Boolean字段的问题:用反射直接赋值
你遇到的报错完全在预料之中——java.lang.Boolean是final类,而Mockito确实无法mock/spy final类(错误提示里已经明确说明了这一点)。但其实你根本不需要mock这个字段:你只是需要给它设置一个具体的布尔值来控制代码分支,反射完全可以做到这一点,而且不需要依赖Mockito的mock能力。
具体解决方案
因为不能修改原类,我们可以在测试类中通过反射直接给RefreshHandlerImpl的readOnlyMode私有字段赋值,步骤如下:
- 移除测试类中
@Mock(name = "readOnlyMode")的Boolean字段(我们不需要mock它,直接设置真实值即可) - 封装一个简单的反射工具方法,用来设置私有字段的值
- 在测试初始化或者测试方法中,调用工具方法给目标字段设置需要的值
修改后的测试类代码示例
import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import java.lang.reflect.Field; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.isEmpty; public class RefreshHandlerImplTest { // 如果原类有其他需要mock的依赖,保留@Mock和@InjectMocks // @Mock // private SomeOtherDependency otherDependency; @InjectMocks private RefreshHandlerImpl refreshHandlerImpl; @BeforeMethod public void setUp() throws Exception { initMocks(this); // 初始化其他mock依赖(如果有的话) // 给readOnlyMode设置初始值,比如true setPrivateField(refreshHandlerImpl, "readOnlyMode", Boolean.TRUE); } // 反射设置私有字段的工具方法,可复用 private void setPrivateField(Object target, String fieldName, Object value) throws NoSuchFieldException, IllegalAccessException { Field field = target.getClass().getDeclaredField(fieldName); field.setAccessible(true); // 打开私有字段的访问权限 field.set(target, value); // 赋值 field.setAccessible(false); // 可选:恢复字段的访问权限,符合封装原则 } @Test public void testRefreshContactsAndBeds_ReturnsZeroContactsWhenCollaboratorsDoes() throws Exception { // 如果需要在这个测试中修改readOnlyMode的值,随时调用工具方法 // setPrivateField(refreshHandlerImpl, "readOnlyMode", Boolean.FALSE); ContactBedRefreshResult result = refreshHandlerImpl.refreshContactsAndBeds(unit, true); assertThat(result.getContacts()).isEmpty(); } }
补充说明
- 如果你的
RefreshHandlerImpl没有其他需要注入的mock依赖,甚至可以不用@InjectMocks,直接new RefreshHandlerImpl()实例化,再用反射赋值即可。 - 为什么不用Mockito的final类mock支持?虽然Mockito可以通过配置(比如
mockito-inline依赖)开启mock final类的能力,但这里完全没必要——我们只是需要一个普通的布尔值,不是需要模拟Boolean类的行为,反射赋值更简单直接。
内容的提问来源于stack exchange,提问作者Jayani Sumudini
相关产品推荐
相关产品推荐

