spring-boot - 在 Spring Boot 的集成测试期间模拟 rest api 调用
问题描述
我有一个 Spring Boot 服务,它通过调用我的身份验证服务来验证每个请求。现在我正在编写一个集成测试。如何在测试自己的 API 时模拟对身份验证服务的请求?
@GetMapping("/pending/task")
@Operation(summary = "Get user's pending task", tags = "UserTask", security = {@SecurityRequirement(name = Constants.AUTH_TOKEN_HEADER)})
@PreAuthorize(Constants.PreAuthorize.ROLE)
public List<UserTaskDto> getPendingTasks(@Valid @RequestParam long courseId){
// internal logic
}
SpringBoot filter will read the token from the header and verify that against auth service using rest. I want to mock that call during this api testing.
测试代码
class UserTaskControllerTest extends ApplicationTests {
@Mock
RestTemplate restTemplate;
@Test
void shouldGiveAllUserPendingTask(){
HttpHeaders headers = new HttpHeaders();
headers.add(Constants.AUTH_TOKEN_HEADER, GENERIC_AUTH_TOKEN);
Task task = FactoryClass.createTask();
UserTask userTask = FactoryClass.createUserTask();
CentralAuthInfo centralAuthInfo = FactoryClass.getCentralAuthInfo();
taskRepository.save(task);
userTask.setTask(task);
userTaskRepository.save(userTask);
UriComponentsBuilder builder = UriComponentsBuilder.fromUriString(USER_PENDING_TASK_BASE_URL)
.queryParam(COURSE_ID, userTask.getCohortId());
when(restTemplate.exchange(ArgumentMatchers.anyString(), ArgumentMatchers.any(HttpMethod.class), ArgumentMatchers.any(HttpEntity.class), ArgumentMatchers.eq(CentralAuthInfo.class))).thenReturn(new ResponseEntity<>(centralAuthInfo, HttpStatus.OK));
ResponseEntity<UserTaskDto> responseEntity = testRestTemplate.exchange(builder.toUriString(), GET, new HttpEntity<>(headers), UserTaskDto.class);
assertThat(responseEntity.getStatusCode()).isEqualTo(200);
}
解决方案
Spring 提供了一个@WithMockUser
可以添加到测试中的方法。我通常使用它WebTextClient
来测试 API 调用。这是一个反应式控制器的例子,但同样适用于非反应式
@Import(SecurityConfig.class)
@WebFluxTest(MyController.class)
class MyControllerTest {
@Autowired
private WebTestClient webTestClient;
...
@Test
@WithMockUser(username="admin",roles={"USER","ADMIN", "ROLE"})
void testPendingTasks() {
webTestClient
.get()
.uri("/pending/task")
.exchange()
.expectStatus()
.isOk();
}
...
}
推荐阅读
- r - R Shiny plot透明背景:低分辨率(轴文本和标签周围的白色像素,以及标题)
- reporting-services - SSRS - 将分组数据放在同一行
- excel - SharePoint 公式:[已创建]+60 天 = 延期日期(但需要是工作日)
- powerbi - PowerBI 中选项卡/页面的基于角色的安全性(不是行级安全性)
- python - 以 x 的倍数从 200 倒计时到 0。X 是用户输入的值(python)
- c# - 发送带有附件的加密电子邮件
- elasticsearch - 我们可以从弹性搜索查询响应中删除数据跟踪吗
- javascript - 开玩笑/反应 - 类型错误:无法读取未定义的属性“touchStart”
- node.js - 使用 App Script 或 Node JS 将列式数据堆叠成行
- javascript - 如何检查对象中的值是否是原始值?