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

Mockito未返回模拟响应:单元测试问题排查与正确实现求助

问题原因分析

你的单元测试中RestTemplate.postForEntity返回null,核心原因是mock的参数类型与待测试方法实际传入的参数不匹配,同时还有几处代码细节错误导致mock逻辑未生效:

  • 请求体类型不匹配:待测试方法里构建的是HttpEntity<String>(请求体是JSON字符串),但测试中mock的是HttpEntity<Map>,Mockito无法匹配到对应的方法调用,因此返回默认的null。
  • 未注入目标URL:待测试类中的postPostURL是通过@Value注入的配置项,测试环境中未赋值,会导致调用时抛出异常或mock匹配失败。
  • 代码细节错误:测试中存在finalDescription未定义、调用方法时对象名错误(lc应为lcAdap)、实体类名称不匹配(Normalized vs Normalize)等问题。
修正后的实现方案

以下是完整的修正单元测试代码,附带关键步骤说明:

import org.mockito.*;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.*;
import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class AdapterTest {

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private Adapter lcAdap;

    @Captor
    private ArgumentCaptor<HttpEntity<String>> entityCaptor;

    @Test
    public void testGetPost_Success() throws Exception {
        // 测试数据准备
        String titleId = "test-title-id";
        List<Normalize> normalizeList = new ArrayList<>();
        String mockJsonResponse = "{ \"data\": \"test\" }";
        String mockPostUrl = "http://test-api.com/post";

        // 注入待测试类中的postPostURL属性
        ReflectionTestUtils.setField(lcAdap, "postPostURL", mockPostUrl);

        // 构建预期的响应
        ResponseEntity<String> mockResponse = new ResponseEntity<>(mockJsonResponse, HttpStatus.OK);

        // 修正mock匹配逻辑:匹配HttpEntity<String>类型的请求体
        when(restTemplate.postForEntity(
                eq(mockPostUrl),
                any(HttpEntity.class),
                eq(String.class)
        )).thenReturn(mockResponse);

        // 执行目标方法
        lcAdap.getPost(titleId, normalizeList);

        // 验证请求是否符合预期(可选)
        verify(restTemplate).postForEntity(eq(mockPostUrl), entityCaptor.capture(), eq(String.class));
        HttpEntity<String> capturedEntity = entityCaptor.getValue();
        assertEquals("application/json", capturedEntity.getHeaders().getFirst(HttpHeaders.CONTENT_TYPE));
        // 可进一步解析请求体,验证内容是否符合业务预期
    }
}
关键修正点说明
  • 匹配正确的请求体类型:将mock中的HttpEntity<Map>改为匹配HttpEntity<String>或用any(HttpEntity.class)模糊匹配,确保Mockito能识别待测试方法的调用。
  • 注入配置属性:通过ReflectionTestUtils.setField给postPostURL赋值,避免因未配置URL导致的异常或匹配失败。
  • 修正代码细节:替换未定义的finalDescription为实际业务参数、统一实体类名称、使用正确的调用对象lcAdap。
  • 添加验证逻辑:通过ArgumentCaptor捕获请求体,验证请求头、请求体内容是否符合预期,提升测试的严谨性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 09:25:14