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 !!
Comments