I have a service that calls a third-party API with RestClient using a default config, when trying to test it using @RestClientTest
the mock server does not detect any incoming requests, I am not sure if its because the RestClient is not being injected correctly or because of the Async behaviour.
How could I test it correctly? Below is the error and the a similar code to what i have
java.lang.AssertionError:
No further requests expected: HTTP GET
0 request(s) executed
@Service
public class MyService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Autowired
RestClient restClient;
@Autowired MyRepository
@Async
public CompletableFuture<Void> fetch(Entity e) {
List<MyDto> info = restClient
.get()
.uri("/get-info" + e.getId())
.attributes(clientRegistrationId("oauth2-client"))
.retrieve()
.body(new ParameterizedTypeReference<List<MyDto>>() {});
repository.saveAll(info);
return CompletableFuturepletedFuture(null);
}
}
@RestClientTest({MyService.class})
@Import({ServiceTest.TestConfig.class})
class MyServiceTest {
@TestConfiguration
static class TestConfig {
@Bean
ClientRegistrationRepository clientRegistrationRepository() {
return new InMemoryClientRegistrationRepository(ClientRegistration.withRegistrationId("oauth2-client")
.authorizationGrantType(AuthorizationGrantType.CLIENT_CREDENTIALS)
.clientId("test")
.tokenUri("test")
.build());
}
@Bean
OAuth2AuthorizedClientService auth2AuthorizedClientService(
ClientRegistrationRepository clientRegistrationRepository) {
return new InMemoryOAuth2AuthorizedClientService(clientRegistrationRepository);
}
@Bean
public Executor asyncTaskExecutor() {
return new SyncTaskExecutor();
}
@Bean
public RestClient restClient(RestClient.Builder restClientBuilder) {
return restClientBuilder
.baseUrl(";)
.defaultHeader("X-API-KEY", "test-api-key")
.build();
}
}
MockRestServiceServer server;
@MockBean
MyRepository myRepository;
@Autowired
private Service service;
@Autowired
RestClient.Builder restClientBuilder;
@BeforeEach
void setUp() {
server = MockRestServiceServer.bindTo(restClientBuilder).build();
}
@Test
void testFetch() {
Entity e = new Entity();
Entity.setId(1L);
server.expect(requestTo(";))
.andRespond(
withSuccess().contentType(MediaType.APPLICATION_JSON));
service.fetchWorkload(e).join();
server.verify();
}
@Configuration
public class RestClientConfig {
@Value("api.key")
private String apiKey;
@Bean
public OAuth2AuthorizedClientManager authorizedClientManager(
ClientRegistrationRepository clientRegistrationRepository,
OAuth2AuthorizedClientService authorizedClientService) {
AuthorizedClientServiceOAuth2AuthorizedClientManager authorizedClientManager =
new AuthorizedClientServiceOAuth2AuthorizedClientManager(
clientRegistrationRepository, authorizedClientService);
authorizedClientManager.setAuthorizedClientProvider(OAuth2AuthorizedClientProviderBuilder.builder()
.authorizationCode()
.build());
return authorizedClientManager;
}
@Bean
public RestClient restClient(OAuth2AuthorizedClientManager authorizedClientManager) {
return RestClient.builder()
.baseUrl(";)
.defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE)
.defaultHeader("X-API-KEY", apiKey)
.requestInterceptor(new OAuth2ClientHttpRequestInterceptor(authorizedClientManager))
.build();
}
}