无法模拟 WebClient

Trouble mocking WebClient

提问人:Riggster 提问时间:10/24/2023 更新时间:10/24/2023 访问量:19

问:

我正在努力编写类似于Spring Boot应用程序中的集成测试的东西。该应用程序是一个 API,具有 3 层 - 控制器、服务和持久性。测试将涉及使用 MockMVC 调用控制器方法。我不想嘲笑任何逻辑,只想嘲笑从 WebClient 返回的内容,这就是我的麻烦所在。我有一个服务类,它使用 WebClient 查询外部 API,但也包括其他逻辑,包括与内部数据库交互。这意味着我不能只是嘲笑服务。我尝试过 Baeldung(嘲笑 Fluent API 中使用的每种方法)、Stevie Leitch(只嘲笑 exchange 函数)的方法,并试图从 rieckpil.de 等来源获得关于 WebClient 中交换方法与检索方法之间差异的见解。

以下是我的控制器和服务是如何实现的,包括我的服务中 WebClient 调用的细节。谁能给我有关如何正确模拟 WebClient 的见解,以便我可以使用 MockMVC 调用控制器,并让服务中的 WebClient 返回模拟响应?

@RestController
@RequestMapping("/api")
public final class UserController {

    private final UserService userService;

    UserController(final UserService service) {
        this.userService = service;
    }

    @GetMapping("/users/{id}")
    public ResponseEntity<User> getById(
        final @PathVariable String id) {
        User payload = userService.getById(id);
        return ResponseEntity
            .status(HttpStatus.OK)
            .contentType(MediaType.APPLICATION_JSON)
            .body(payload);
    }

    @GetMapping("/users")
    public ResponseEntity<List<User>> getAll() {
        List<user> payload = userService.getAll();
        return ResponseEntity
            .status(HttpStatus.OK)
            .contentType(MediaType.APPLICATION_JSON)
            .body(payload);
    }
}
@Component
public class UserService {

    private String url;
    private final WebClient webClient;
    private final Repository repository;

    public UserService(final WebClient webClient, final String uri, final Repository repository) {
        this.webClient = webClient;
        this.uri = uri;
        this.repository = repository;
    }

    public List<User> getAll() {
        ArrayList<User> responses = webClient.get()
                .uri(uri)
                .accept(MediaType.APPLICATION_JSON)
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference<List<User>>() {})
                .block();
        // Other unrelated logic
        return responses;
    }

    public User getById(final String id) {
        String finalURI = uri + id;
        Optional<User> response = Optional
                .ofNullable(webClient.get()
                .uri(finalURI)
                .accept(MediaType.APPLICATION_JSON)
                .exchangeToMono(clientResponse -> {
                    switch (clientResponse.rawStatusCode()) {
                        case 200:
                            return clientResponse.bodyToMono(User.class);
                        case 404:
                            throw new UserNotFoundException(id);
                        default:
                            return Mono.empty();
                        }
                })
                .block());
        // Other unrelated logic
        return response.get();
    }
}
集成测试 spring-webclient

评论


答: 暂无答案