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
相关产品推荐
相关产品推荐

