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

Spring项目中方法内创建的RestTemplate如何编写JUnit测试用例?

解决方法

方案一:重构代码(推荐)

原代码直接在方法内实例化RestTemplate,属于硬编码依赖,既不利于测试也不利于后续扩展。建议通过构造注入将RestTemplate作为外部依赖传入:

修改Post类

public class Post {

    private final RestTemplate restTemplate;

    // 构造注入RestTemplate
    public Post(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public <T> ResponseEntity<T> postRequest(Object request) {
        // 省略Header构建逻辑
        return restTemplate.exchange(......);
    }
}

编写JUnit测试用例

用Mockito mockRestTemplate,验证方法调用逻辑:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.ResponseEntity;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class PostTest {

    @Mock
    private RestTemplate restTemplate;

    @InjectMocks
    private Post post;

    @Test
    void postRequest_ShouldCallExchange() {
        // 模拟请求参数
        Object request = new Object();
        // 模拟exchange方法返回值
        ResponseEntity<String> mockResponse = ResponseEntity.ok("success");
        when(restTemplate.exchange(anyString(), any(), any(), eq(String.class)))
                .thenReturn(mockResponse);

        // 调用测试方法
        ResponseEntity<String> response = post.postRequest(request);

        // 验证exchange方法被正确调用
        verify(restTemplate).exchange(anyString(), any(), any(), eq(String.class));
        // 验证返回值符合预期
        assert response.getStatusCode().is2xxSuccessful();
    }
}

方案二:不修改原代码,用PowerMock mock构造方法

如果无法改动原业务代码,可借助PowerMock拦截new RestTemplate()的构造调用,返回预设的mock实例:

依赖配置(Maven示例)

<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-module-junit4</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.powermock</groupId>
    <artifactId>powermock-api-mockito2</artifactId>
    <version>2.0.9</version>
    <scope>test</scope>
</dependency>

编写JUnit测试用例

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Post.class) // 指定需要mock构造方法的类
public class PostTest {

    @Test
    void postRequest_ShouldUseMockRestTemplate() throws Exception {
        // 创建RestTemplate的mock实例
        RestTemplate mockRestTemplate = PowerMockito.mock(RestTemplate.class);
        // 拦截Post类中new RestTemplate()的调用,返回mock实例
        PowerMockito.whenNew(RestTemplate.class).withNoArguments().thenReturn(mockRestTemplate);

        // 模拟exchange方法的返回值
        ResponseEntity<String> mockResponse = ResponseEntity.ok("success");
        when(mockRestTemplate.exchange(anyString(), any(), any(), eq(String.class)))
                .thenReturn(mockResponse);

        // 调用目标方法
        Post post = new Post();
        ResponseEntity<String> response = post.postRequest(new Object());

        // 验证exchange方法被正确调用
        verify(mockRestTemplate).exchange(anyString(), any(), any(), eq(String.class));
        assert response.getStatusCode().is2xxSuccessful();
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 01:57:18