Testing REST Controllers with Spring Boot @RestClientTest

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

Subscribe
Notify of
guest
2 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode