MockWebServer正在实际调用我的服务,而不是模拟它们。

huangapple go评论56阅读模式
英文:

MockWebServer is making actual calls to my service instead of mocking them

问题

我目前正在使用Spring Boot开发微服务应用程序。我尝试为我的user-service WebClient编写一个使用MockWebServer的测试。然而,看起来MockWebServer正在向服务发送真实请求,而不是模拟它。即使服务正在运行,这个问题仍然存在,可能是因为我使用了Eureka发现来进行服务注册。

public class UserClientTest {
    private MockWebServer mockWebServer;
    private UserClient userClient;
    @Autowired
    WebClient.Builder webClientBuilder;

    @BeforeEach
    public void setup() throws IOException {
        mockWebServer = new MockWebServer();
        mockWebServer.start();

        webClientBuilder = WebClient.builder()
                .baseUrl(mockWebServer.url("/users").toString());
        userClient = new UserClient(webClientBuilder);
    }

    @AfterEach
    public void tearDown() throws IOException {
        mockWebServer.shutdown();
    }

    @Test
    @DisplayName("Should create a new user")
    public void shouldCreateANewUser() {
        UserResponse mockResponse = new UserResponse(1L, "john_doe", "john@example.com");
        mockWebServer.enqueue(
                new MockResponse().setResponseCode(201)
                .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .setBody(new Gson().toJson(mockResponse))
        );

        // 执行实际的方法调用
        UserRequest userRequest = new UserRequest("john_doe", "password", "john@example.com");
        Mono<UserResponse> createUserMono = userClient.createUser(userRequest);
        StepVerifier.create(createUserMono)
                .expectNext(mockResponse)
                .verifyComplete();
    }
}
@Component
public class UserClient {
    private static final String BASE_URL = "http://user-service";
    private final WebClient webClient;

    public UserClient(@Autowired WebClient.Builder webClient) {
        this.webClient = webClient.baseUrl(BASE_URL).build();
    }

    public Mono<UserResponse> createUser(UserRequest userRequest) {
        return webClient.post()
                .uri("/users")
                .bodyValue(userRequest)
                .retrieve()
                .bodyToMono(UserResponse.class);
    }
}
@Configuration
public class WebClientConfig {

    @Bean
    @LoadBalanced
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}
英文:

I am currently developing a microservices app using Spring Boot. I am attempting to write a test for my user-service WebClient using MockWebServer. However, it appears that MockWebServer is sending a real request to the service instead of mocking it. This issue persists even when the service is running, likely due to my usage of Eureka discovery for service registration.

public class UserClientTest {
    private MockWebServer mockWebServer;
    private UserClient userClient;
    @Autowired
    WebClient.Builder webClientBuilder;

    @BeforeEach
    public void setup() throws IOException {
        mockWebServer = new MockWebServer();
        mockWebServer.start();

        webClientBuilder = WebClient.builder()
                .baseUrl(mockWebServer.url(&quot;/users&quot;).toString());
        userClient = new UserClient(webClientBuilder);
    }

    @AfterEach
    public void tearDown() throws IOException {
        mockWebServer.shutdown();
    }

    @Test
    @DisplayName(&quot;Should create a new user&quot;)
    public void shouldCreateANewUser() {
        UserResponse mockResponse = new UserResponse(1L, &quot;john_doe&quot;, &quot;john@example.com&quot;);
        mockWebServer.enqueue(
                new MockResponse().setResponseCode(201)
                .setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .setBody(new Gson().toJson(mockResponse))
        );

        // Perform the actual method call
        UserRequest userRequest = new UserRequest(&quot;john_doe&quot;, &quot;password&quot;, &quot;john@example.com&quot;);
        Mono&lt;UserResponse&gt; createUserMono = userClient.createUser(userRequest);
        StepVerifier.create(createUserMono)
                .expectNext(mockResponse)
                .verifyComplete();
    }

}
@Component
public class UserClient {
    private static final String BASE_URL = &quot;http://user-service&quot;;
    private final WebClient webClient;

    public UserClient(@Autowired WebClient.Builder webClient) {
        this.webClient = webClient.baseUrl(BASE_URL).build();
    }

    public Mono&lt;UserResponse&gt; createUser(UserRequest userRequest) {
        return webClient.post()
                .uri(&quot;/users&quot;)
                .bodyValue(userRequest)
                .retrieve()
                .bodyToMono(UserResponse.class);
    }
}
@Configuration
public class WebClientConfig {

    @Bean
    @LoadBalanced
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}

答案1

得分: 1

我认为这是因为以下的UserClient的构造函数总是将WebClient的基本URL固定为http://user-service,这会覆盖你在测试中配置的设置:

@Component
public class UserClient {
    public static final String BASE_URL = "http://user-service";
    private final WebClient webClient;

    public UserClient(@Autowired WebClient.Builder webClient) {
        this.webClient = webClient.baseUrl(BASE_URL).build();
    }
}

为了更加灵活,它应该尊重输入WebClient.Builder的设置:

public UserClient(@Autowired WebClient.Builder webClient) {
    this.webClient = webClient.build();
}

然后客户端可以自己定义基本URL,例如:

@Configuration
public class WebClientConfig {

    @Bean
    @LoadBalanced
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder().baseUrl(UserClient.BASE_URL);
    }
}
英文:

I think it is because the following UserClient 's constructor always fix the WebClient 's base URL to http://user-service which override the setting you configure in the test :

@Component
public class UserClient {
    public static final String BASE_URL = &quot;http://user-service&quot;;
    private final WebClient webClient;

    public UserClient(@Autowired WebClient.Builder webClient) {
        this.webClient = webClient.baseUrl(BASE_URL).build();
    }
}

To be more flexible , it should respect the setting of the input WebClient.Builder :

    public UserClient(@Autowired WebClient.Builder webClient) {
        this.webClient = webClient.build();
    }

The client can then define the base URL by themself such as :

@Configuration
public class WebClientConfig {

    @Bean
    @LoadBalanced
    public WebClient.Builder webClientBuilder() {
        return WebClient.builder().baseUrl(UserClient.BASE_URL);
    }
}

huangapple
  • 本文由 发表于 2023年5月28日 08:44:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/76349560.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定