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

如何测试含动态数据的类?final依赖对象的单元测试方案

解决final成员变量ParserBets的测试mock问题

针对你要测试PageBets.refreshEvents()、需要控制parser.getEvents()行为的场景,不需要写代理,有几个更简洁的方案:

1. 重构构造器,支持依赖注入(推荐)

当前代码的问题在于构造器内部硬编码调用initParser()初始化final的parser,导致测试时无法替换。最干净的做法是重构构造器,把parser作为参数传入:

// 保留原有的生产用构造器,兼容现有代码
public PageBets(String uri) throws MalformedURLException, URISyntaxException {
    this(initParser());
    try {
        // 原有的uri相关初始化逻辑...
        this.events = refreshEvents();
    } catch (URISyntaxException | MalformedURLException e) {
        log.debug("Not correct format link: {}", uri, e);
        throw e;
    }
}

// 新增供测试使用的构造器(可以设为包私有,或用@VisibleForTesting注解标记)
PageBets(ParserBets parser) {
    this.parser = parser;
    this.events = new TreeSet<>(); // 初始化空集合,或者根据测试需求调整
}

测试时直接传入mock的ParserBets实例即可,完全不受成员变量final的限制:

// 假设用Mockito创建mock
ParserBets mockParser = Mockito.mock(ParserBets.class);
// 预设getEvents的返回值
when(mockParser.getEvents(any(PageBets.class))).thenReturn(new TreeSet<>(/* 测试用Event集合 */));

// 创建测试用的PageBets实例
PageBets testPage = new PageBets(mockParser);
// 调用refreshEvents并验证逻辑
TreeSet<Event> result = testPage.refreshEvents();
// 断言结果符合预期

2. 使用Mocking框架直接mock final类(如果ParserBets是final类)

如果ParserBets本身是final类,Mockito 2.x及以上版本支持mock final类,只需简单配置:

  • 在src/test/resources/mockito-extensions目录下创建文件org.mockito.plugins.MockMaker
  • 文件内容写入:mock-maker-inline

之后就可以直接mock final的ParserBets类,配合构造器注入使用,步骤和上面一致。

3. 静态方法mock(不推荐,仅当无法重构原代码时用)

如果完全不能修改PageBets的构造器,可以用PowerMock来mockinitParser()静态方法,让它返回mock的ParserBets:

@RunWith(PowerMockRunner.class)
@PrepareForTest(PageBets.class)
public class PageBetsTest {
    @Test
    public void testRefreshEvents() throws Exception {
        ParserBets mockParser = Mockito.mock(ParserBets.class);
        when(mockParser.getEvents(any(PageBets.class))).thenReturn(/* 测试数据 */);
        
        // mock initParser方法返回mock对象
        PowerMockito.mockStatic(PageBets.class);
        when(PageBets.initParser()).thenReturn(mockParser);
        
        // 创建PageBets实例
        PageBets testPage = new PageBets("test-uri");
        // 执行测试并验证
    }
}

这种方式会增加测试复杂度,且PowerMock可能和其他测试框架存在兼容性问题,优先推荐前两种方案。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 12:15:24