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

使用@Mock注解时ContentProperties为null,Mockito单元测试求助

解决Mockito中@Mock注解ContentProperties对象为null的问题

我来帮你拆解一下你遇到的问题,并且给出两种针对性的解决方案:

问题根源

你当前的测试类同时混用了Mockito的@RunWith(MockitoJUnitRunner.class)和Spring的@ContextConfiguration注解,这会导致JUnit的Runner机制冲突。MockitoJUnitRunner本来负责初始化@Mock和@InjectMocks标注的字段,但一旦Spring的TestContextRunner接管测试执行,Mockito的注解处理逻辑就可能失效,进而导致@Mock声明的ContentProperties对象为null。

另外,你的PageBuilderService主类里缺少ContentProperties的依赖注入注解,这会导致即使测试中模拟了该对象,服务类也无法获取到它,这个小细节也需要修正。


解决方案一:纯Mockito单元测试(无需Spring上下文)

如果你的测试只是验证PageBuilderService的业务逻辑,不需要加载Spring容器,推荐用纯Mockito的方式:

1. 修改测试类

移除所有Spring相关的注解,只保留Mockito的注解,确保@Mock能被正确初始化:

@RunWith(MockitoJUnitRunner.class) 
class PageBuilderServiceTest { 
    @Mock 
    private CService cs; 
    @Mock 
    private RService rs; 
    @Mock 
    private ContentProperties contentProperties; // 现在@Mock会被Mockito正确初始化
    
    @InjectMocks 
    private PageBuilderService pageBuilderService ; 

    @ParameterizedTest 
    @EnumSource(HompageEnum.class) 
    @DisplayName("Testing doIt with EnumSource") 
    public void checkRowposition(HompageEnum homepageEnum) { 
        // 打桩模拟行为
        Mockito.when(contentProperties.getPageFolder(anyString())).thenReturn("http://google.com");
        
        // 执行被测试方法
        Queue<String> result = pageBuilderService.getStaticContent("test-url");
        
        // 添加断言或验证逻辑,比如验证方法调用、结果是否符合预期
        Mockito.verify(contentProperties).getPageFolder("test-url");
    } 
}

2. 修正主类的依赖注入

在PageBuilderService中给contentProperties加上@Autowired注解,确保依赖能被注入:

@Service("pgService") 
public class PageBuilderService { 
    @Autowired 
    private RService rs; 
    @Autowired 
    private CService cs; 
    @Autowired // 补上这个注解,让Spring或Mockito能注入该依赖
    private ContentProperties contentProperties;

    public Queue<String> getPaginatedContent(HomepageRequest homepageRequest) { 
        Queue<String> staticContent = getStaticContent(homepageRequest.getUrl()); 
        return staticContent; 
    } 

    public Queue<String> getStaticContent(String url) { 
        Queue<String> files = new LinkedList<>(); 
        String dir = contentProperties.getPageFolder(url); 
        return null; 
    } 
}

解决方案二:结合Spring上下文测试(需要加载Spring配置)

如果你的测试必须依赖Spring上下文(比如需要读取配置文件、加载其他Spring组件),那么改用Spring测试框架结合@MockBean注解:

修改测试类

用Spring的测试扩展替代MockitoRunner,并用@MockBean替代@Mock,它会将模拟对象注册到Spring上下文中,确保服务类能获取到:

// JUnit 5 写法,用SpringExtension
@ExtendWith(SpringExtension.class)
@ActiveProfiles(profiles = "staging") 
@ContextConfiguration(loader = AnnotationConfigContextLoader.class , classes = {ContentProperties.class , MasterPropertiesFactory.class }) 
class PageBuilderServiceTest { 
    @MockBean 
    private CService cs; 
    @MockBean 
    private RService rs; 
    @MockBean // 用@MockBean替代@Mock,让Spring上下文管理这个模拟对象
    private ContentProperties contentProperties; 

    @Autowired // 从Spring上下文注入服务类,它会自动使用@MockBean的依赖
    private PageBuilderService pageBuilderService ; 

    @ParameterizedTest 
    @EnumSource(HompageEnum.class) 
    @DisplayName("Testing doIt with EnumSource") 
    public void checkRowposition(HompageEnum homepageEnum) { 
        Mockito.when(contentProperties.getPageFolder(anyString())).thenReturn("http://google.com"); 
        
        // 执行测试逻辑
        Queue<String> result = pageBuilderService.getStaticContent("test-url");
        
        // 验证或断言
    } 
}

这种方式下,Spring会负责管理所有Bean,@MockBean创建的模拟对象会替换掉上下文中对应的真实Bean,从而实现依赖模拟。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:44:44