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

SpringBoot2.7.5+Java11:JUnit5中Mock同步调用的WebClient

问题解决:SpringBoot测试中Autowired对象为空+Mock WebClient失败

问题原因分析

  1. 上下文加载范围错误:你在@SpringBootTest中指定了classes = { Cicrawlrequesttrigger.class },如果这个类不是项目启动类,也未包含StockAvailibilityStrategy和WebClient配置类的扫描逻辑,Spring容器不会初始化这些Bean,自然@Autowired会返回空值。
  2. 注解混用错误:
    • 要Mock Spring容器中的Bean,需用@MockBean而非@Mock或@Autowired;
    • @InjectMocks是Mockito用于将Mock对象注入目标类的注解,不能和@Autowired混用在同一字段上。
  3. 冗余注解:@SpringBootTest已集成SpringExtension,无需额外添加@ExtendWith(SpringExtension.class)。

解决方案步骤

1. 修正测试类注解配置

  • 要么去掉classes属性,让@SpringBootTest加载项目启动类对应的完整上下文;
  • 要么指定包含WebClient配置类和StockAvailibilityStrategy的类(比如项目启动类)。
  • 用@MockBean配合@Qualifier来Mock目标WebClient。

2. Mock WebClient调用逻辑

WebClient采用链式调用,需Mock它的get()/post()、uri()、retrieve()/exchange()等方法,而非直接Mock业务方法(比如你之前的Strategy.invokLoc)。

修正后的测试类示例

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) // 去掉classes限制,或指定项目启动类
@DirtiesContext
@ActiveProfiles("test")
public class StrategyTest {
    @Autowired
    private StockAvailibilityStrategy stockAvailibilityStrategy;

    @MockBean
    @Qualifier("kWebclient")
    private WebClient kWebclient;

    private Executor executor;

    @BeforeEach
    public void setUp() {
        executor = Executors.newFixedThreadPool(1);
    }

    @Test
    void testStrategyOptimise() {
        // 1. 构建Mock的WebClient响应
        String mockResponse = "[{response}]";
        // Mock WebClient的链式调用节点
        WebClient.RequestHeadersUriSpec<?> requestHeadersUriSpec = Mockito.mock(WebClient.RequestHeadersUriSpec.class);
        WebClient.ResponseSpec responseSpec = Mockito.mock(WebClient.ResponseSpec.class);

        Mockito.when(kWebclient.get()).thenReturn(requestHeadersUriSpec);
        Mockito.when(requestHeadersUriSpec.uri(Mockito.anyString())).thenReturn(requestHeadersUriSpec);
        Mockito.when(requestHeadersUriSpec.retrieve()).thenReturn(responseSpec);
        Mockito.when(responseSpec.toEntity(String.class))
                .thenReturn(Mono.just(new ResponseEntity<>(mockResponse, HttpStatus.OK)));

        // 2. 准备测试数据
        CentralRepoLite central = getCentralRepoLite();
        CReady cy = setTestCReady();

        // 3. 执行测试方法
        stockAvailibilityStrategy.optimise(testCRequest, StoreInfo, centralRepoEntities, cRepo, executor);

        // 4. 断言结果
        assertNotNull(cy);
    }
}

补充说明

  • 如果StockAvailibilityStrategy通过构造注入依赖WebClient,@MockBean会自动将Mock的WebClient注入到该Bean中,无需额外处理;
  • 若不需要完整Spring上下文,也可使用纯Mockito测试(@ExtendWith(MockitoExtension.class)),此时用@InjectMocks注入StockAvailibilityStrategy,用@Mock创建WebClient的Mock对象,适合不需要其他Spring Bean的场景:
@ExtendWith(MockitoExtension.class)
public class StrategyTest {
    @InjectMocks
    private StockAvailibilityStrategy stockAvailibilityStrategy;

    @Mock
    @Qualifier("kWebclient")
    private WebClient kWebclient;

    // ... 测试逻辑同上
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:43:11