Search code examples
spring-bootspring-restspring-boot-test

Using @RestClientTest in spring boot test


I want to write a simple test using @RestClientTest for the component below (NOTE: I can do it without using @RestClientTest and mocking dependent beans which works fine.).

@Slf4j
@Component
@RequiredArgsConstructor
public class NotificationSender {

    private final ApplicationSettings settings;
    private final RestTemplate restTemplate;

    public ResponseEntity<String> sendNotification(UserNotification userNotification)
            throws URISyntaxException {
            // Some modifications to request message as required
            return restTemplate.exchange(new RequestEntity<>(userNotification, HttpMethod.POST, new URI(settings.getNotificationUrl())), String.class);
    }
}

And the test;

@RunWith(SpringRunner.class)
@RestClientTest(NotificationSender.class)
@ActiveProfiles("local-test")
public class NotificationSenderTest {

    @MockBean
    private ApplicationSettings settings;
    @Autowired
    private MockRestServiceServer server;
    @Autowired
    private NotificationSender messageSender;

    @Test
    public void testSendNotification() throws Exception {
        String url = "/test/notification";
        UserNotification userNotification = buildDummyUserNotification();
        when(settings.getNotificationUrl()).thenReturn(url);
        this.server.expect(requestTo(url)).andRespond(withSuccess());

        ResponseEntity<String> response = messageSender.sendNotification(userNotification );

        assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
    }

    private UserNotification buildDummyUserNotification() {
     // Build and return a sample message
    }
}

But i get error that No qualifying bean of type 'org.springframework.web.client.RestTemplate' available. Which is right of course as i havn't mocked it or used @ContextConfiguration to load it.

Isn't @RestClientTest configures a RestTemplate? or i have understood it wrong?


Solution

  • Found it! Since i was using a bean that has a RestTemplate injected directly, we have to add @AutoConfigureWebClient(registerRestTemplate = true) to the test which solves this.

    This was in the javadoc of @RestClientTest which i seem to have ignored previously.

    Test which succeeds;

    @RunWith(SpringRunner.class)
    @RestClientTest(NotificationSender.class)
    @ActiveProfiles("local-test")
    @AutoConfigureWebClient(registerRestTemplate = true)
    public class NotificationSenderTest {
    
        @MockBean
        private ApplicationSettings settings;
        @Autowired
        private MockRestServiceServer server;
        @Autowired
        private NotificationSender messageSender;
    
        @Test
        public void testSendNotification() throws Exception {
            String url = "/test/notification";
            UserNotification userNotification = buildDummyUserNotification();
            when(settings.getNotificationUrl()).thenReturn(url);
            this.server.expect(requestTo(url)).andRespond(withSuccess());
    
            ResponseEntity<String> response = messageSender.sendNotification(userNotification );
    
            assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
        }
    
        private UserNotification buildDummyUserNotification() {
         // Build and return a sample message
        }
    }