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

如何使用Mockito模拟Do-While循环?

如何用Mockito模拟Do-While循环分页场景

先理清楚问题:你的业务方法getAllApplesByServer用do-while循环分页拉取苹果数据,直到某一页返回空列表才停止。要测试这个逻辑,得让Mockito模拟WebClient的多次调用——前几次返回有数据的页,最后一次返回空页,触发循环结束。

核心解决办法

Mockito支持给同一个方法调用设置连续返回值,用thenReturn(value1, value2)的写法就行:第一次调用返回value1,第二次返回value2,以此类推。对应到你的分页场景,就是让WebClient的bodyToFlux第一次返回带数据的Flux,第二次返回空Flux,这样collectList().block()就会先拿到非空列表,再拿到空列表,刚好触发do-while的退出条件。

修正后的测试代码

先把你原测试里的笔误改了(比如bodyToFlux(Strategy.class)应该是bodyToFlux(Apple.class),还有变量名拼写错误),然后写正确的模拟逻辑:

@Test
void getAllApplesByServer_withPagination() throws SSLException {
    // 准备测试数据
    Apple apple1 = new Apple();
    apple1.setName("RedApple");
    apple1.setEntityVersion("v1");
    Apple apple2 = new Apple();
    apple2.setName("GreenApple");
    apple2.setEntityVersion("v1");
    List<Apple> firstPage = Arrays.asList(apple1, apple2);
    List<Apple> emptyPage = Collections.emptyList();

    // 模拟WebClient链式调用,设置连续返回值
    when(webClientMock.get()).thenReturn(requestHeadersUriSpec);
    when(requestHeadersUriSpec.uri(anyString())).thenReturn(requestBodyMock);
    when(requestBodyMock.header(anyString(), anyString())).thenReturn(requestBodyMock);
    when(requestBodyMock.retrieve()).thenReturn(responseMock);
    // 第一次返回有数据的Flux,第二次返回空Flux
    when(responseMock.bodyToFlux(Apple.class))
            .thenReturn(Flux.fromIterable(firstPage))
            .thenReturn(Flux.empty());

    // 执行测试方法
    List<Apple> result = appleService.getAllApplesByServer("farm");

    // 断言结果:合并了第一页的所有数据
    assertEquals(2, result.size());
    assertTrue(result.contains(apple1));
    assertTrue(result.contains(apple2));

    // 验证WebClient的get方法被调用2次(对应2页请求)
    verify(webClientMock, times(2)).get();
    // 验证uri方法被调用2次
    verify(requestHeadersUriSpec, times(2)).uri(anyString());
}

细节说明

  • 连续返回值的作用:thenReturn(Flux.fromIterable(firstPage)).thenReturn(Flux.empty())表示第一次调用bodyToFlux时返回2个Apple,第二次返回空,这样do-while循环会执行两次——第一次加数据,第二次拿到空列表,退出循环。
  • 验证调用次数:用verify(mock, times(n))确认分页请求次数对不对,这里循环跑了2次,所以WebClient的get方法得被调用2次。
  • 笔误修正:原业务方法里return allappleList是拼写错了,应该是return allAppleList;原测试里bodyToFlux(Strategy.class)类型不匹配,要改成Apple.class,不然会报错。

扩展:验证分页参数

如果你想确认每次请求的page参数是不是正确(比如第一次page=1,第二次page=2),可以用ArgumentCaptor捕获uri参数来检查:

// 定义捕获器抓uri字符串
ArgumentCaptor<String> uriCaptor = ArgumentCaptor.forClass(String.class);
// 验证uri方法被调用2次,同时捕获参数
verify(requestHeadersUriSpec, times(2)).uri(uriCaptor.capture());
// 获取所有捕获的uri
List<String> capturedUris = uriCaptor.getAllValues();
// 检查第一个uri带page=1,第二个带page=2
assertTrue(capturedUris.get(0).contains("page=1"));
assertTrue(capturedUris.get(1).contains("page=2"));

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:50:44