Search code examples
springspring-bootmockingjunit5rest-client

Spring 6.1 RestClient JUnit Mock Test


I have a Spring 6.1 RestClient:

@Service
@RequiredArgsConstructor
public class ProductServiceClient {

  @Value("${spring.client.product.url}")
  private final String baseUrl;

  private final RestClient restClient;

  public List<ProductPriceDto> getProductPrices(UUID productId, LocalDate date) {
    String url = baseUrl + "/products/" + productId + "/prices/?date=" + date;

    return restClient.get().uri(url).retrieve().body(new ParameterizedTypeReference<>() {});
  }
}

And the Spring Configuration:

@Configuration
public class RestClientConfig {

  @Bean
  public RestClient restClient() {
    return RestClient.create();
  }

}

Now I want to have a JUnit5 test to mock this client. Can someone please give me a sample? Since this client is also been called from other tests, I am wondring how to mock it there too=?


Solution

  • I solved my problem with okhttp3.mockwebserver.MockWebServer

    @SpringBootTest
    class ProductServiceClientTest {
     private MockWebServer mockWebServer;
     private ProductServiceClient productServiceClient;
    
      @BeforeEach
      void setUp() throws IOException {
        mockWebServer = new MockWebServer();
        mockWebServer.start();
        // Configure the RestClient to point to the MockWebServer URL
        RestClient restClient = RestClient.builder().baseUrl(mockWebServer.url("/").toString()).build();
        // Configure the ProductServiceClient to use the mocked vales
        productServiceClient = new ProductServiceClient(mockWebServer.url("/").toString(), restClient);
      }
    
      @AfterEach
      void tearDown() throws IOException {
        mockWebServer.shutdown();
      }
    
      @Test
      void testGetProductPrices() throws Exception {
        UUID productId = UUID.randomUUID();
        LocalDate date = LocalDate.now();
    
        var expectedResponse =
            List.of(
                new ProductPriceDto(date, 49L, 500), new ProductPriceDto(date.plusDays(1), 39L, 700));
        ObjectMapper mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        String jsonResponse = mapper.writeValueAsString(expectedResponse);
    
        mockWebServer.enqueue(
            new MockResponse()
                .setBody(jsonResponse)
                .addHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE));
    
        List<ProductPriceDto> actualResponse = productServiceClient.getProductPrices(productId, date);
    
        assertEquals(expectedResponse, actualResponse);
      }
    }