Learn to use @RestClientTest annotation provided by Spring boot test module that focuses only on beans that use RestTemplateBuilder
or RestTemplate
.
1. @RestClientTest annotation
In spring framework, @RestClientTest
is one of the test specific annotations that disables full auto-configuration and instead apply only configuration relevant to specific tests.
@RestClientTest
annotation is used to test service layer which uses RestTemplate
to interact with external services.
This annotation disables full auto-configuration and instead apply only configuration relevant to rest client tests.
To import the annotation in application, include spring-boot-starter-test
starter module into pom.xml
file.
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
2. Testing service which uses RestTemplateBuilder
If the service under test uses RestTemplateBuilder
to obtain the RestTemplate
for invoking external services, we can use @RestClientTest
annotation directly over test class.
2.1. Service
import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import com.springexamples.demo.service.UserService; @Service public class UserServiceImpl implements UserService { RestTemplate restTemplate; @Autowired public UserServiceImpl(RestTemplateBuilder restTemplateBuilder) { restTemplate = restTemplateBuilder.build(); } @Override public String testUserService() { final String uri = "http://localhost:8080/users"; String result = restTemplate.getForObject(uri, String.class); System.out.println(result); return result; } }
2.2. Test class
import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.test.web.client.match.MockRestRequestMatchers.requestTo; import static org.springframework.test.web.client.response.MockRestResponseCreators.withSuccess; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.web.client.RestClientTest; import org.springframework.http.MediaType; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.web.client.MockRestServiceServer; import com.springexamples.demo.service.UserService; import com.springexamples.demo.service.impl.UserServiceImpl; @RunWith(SpringRunner.class) @RestClientTest(UserServiceImpl.class) public class UserServiceTest { @Autowired private MockRestServiceServer server; @Autowired private UserService client; @Test public void testServiceCall() { this.server.expect(requestTo("http://localhost:8080/users")) .andRespond(withSuccess("<users></users>", MediaType.TEXT_PLAIN)); String userServiceResponse = client.testUserService(); assertThat(userServiceResponse).isEqualTo("<users></users>"); } }
3. Testing service which DOES NOT use RestTemplateBuilder
If the service uner test injects a RestTemplate
directly, we can can add @AutoConfigureWebClient(registerRestTemplate=true)
over test class.
Also, if you are creating RestTemplate
bean in main application configuration then you will need to enable bean overriding to true.
spring.main.allow-bean-definition-overriding=true
2.1. Service
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import com.springexamples.demo.service.UserService; @Service public class UserServiceImpl implements UserService { @Autowired RestTemplate restTemplate; @Override public String testUserService() { final String uri = "http://localhost:8080/users"; String result = restTemplate.getForObject(uri, String.class); System.out.println(result); return result; } }
2.2. Test class
@RunWith(SpringRunner.class) @RestClientTest(UserServiceImpl.class) @AutoConfigureWebClient(registerRestTemplate = true) public class UserServiceTest { @Autowired private MockRestServiceServer server; @Autowired private UserService client; @Test public void testServiceCall() { this.server.expect(requestTo("http://localhost:8080/users")) .andRespond(withSuccess("<users></users>", MediaType.TEXT_PLAIN)); String userServiceResponse = client.testUserService(); assertThat(userServiceResponse).isEqualTo("<users></users>"); } }
Drop me your questions related to Spring Boot @RestClientTest annotation as discussed above.
Happy Learning !!