In this article we will show you how to perform a GET request in Spring using RestTemplate. We will take you through a simple integration test example to be able to test a GET endpoint in a Spring Boot application.
Let’s start!
Setup
For the examples shown throughout this article, we will be using the same codebase we’ve shown in our previous Spring articles. You can see the latest version in our article “Exception Handling in Spring Rest Services in Java”.
In this article will look at our GET endpoint only, and write an integration test for it. Our GET endpoint looks like this:
@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<Customer> findCustomer(@PathVariable("id") Long id) {
return repository.findById(id)
.onFailureDo(e -> {
if (e.exception() instanceof CustomerNotFound) {
return ResponseEntity.notFound().build();
} else {
return ResponseEntity.internalServerError().build();
}
}).response();
}
As you can see in this example, we are using a custom Either
monad to handle the responses, but for the purpose of this article you won’t have to worry about implementation details. Integration testing is a kind of black box test, we only care about the response, so the internals of the service should be completely opaque for the purposes of testing.
One more thing you’ll need in your application to be able to test it, is the Spring Boot test dependencies. You can import them by importing the Spring Boot starter test package in your build.gradle
file:
dependencies {
implementation 'org.springframework.boot:spring-boot-starter'
implementation("org.springframework.boot:spring-boot-starter-web")
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
You will also notice that we are not specifying the version in our dependency import, this is because we have previously defined the Spring Boot version in our plugins
section:
plugins {
id 'java'
id 'org.springframework.boot' version '2.7.6'
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
Now that we have the very basics of our Spring Boot application, we can now start with out test. If for any reason you need help to set up your initial application, you can check our article “How to Bootstrap a Spring Boot Application”.
Let’s start looking at our integration test then!
Test Get Request in Spring
There are different ways to test a GET request in Spring, depending on what your needs are. We will start by looking at getForEntity
method, let’s see how it works.
Using GetForEntity method
The getForEntity
method allows us to easily test a GET endpoint in our application by sending a simple GET request in Spring, although it has some limitations. Let’s see how it works:
package com.theboreddev.springbootjava;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class CustomerControllerIntegrationTest {
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate template;
@Test
public void shouldReturn404WhenCustomerForAGivenIdDoesNotExist() {
final ResponseEntity<Customer> response = template.getForEntity(String.format("http://localhost:%d/api/customers/4", port), Customer.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.NOT_FOUND);
}
}
You will see that initially we have just added an integration test to check that, when the customer does not exist, we receive the expected 404 (NOT_FOUND) response.
Once we have this initial test passing, we now need to test that an existing customer can be retrieved. To do so, we’ll provide a fake customer repository that will always contain a predefined number of customers, just for the purpose of easily testing our GET endpoint in this article. In a real application we’d normally populate data using our POST endpoint first, and the utilise a GET request in Spring to check that the data has been persisted.
Our fake customer repository will look something like this:
@Component("inMemoryCostumersRepository")
public class InMemoryCustomersRepository implements CustomersRepository {
private final Map<Long, Customer> customers = Map.of(
1L, new Customer(1L, "John Smith", 33),
2L, new Customer(2L, "Leonard Randolph", 42),
3L, new Customer(3L, "Margaret McGuinness", 27)
);
@Override
public Either<Exception, Customer> create(Customer customer) {
final Customer newCustomer = new Customer((long) customers.size(), customer.name(), customer.age());
customers.put(newCustomer.id(), newCustomer);
return new Either.Success<>(newCustomer);
}
@Override
public Either<Exception, Customer> findById(Long id) {
final Customer existing = customers.get(id);
if (existing != null) {
return new Either.Success<>(existing);
}
return new Either.Failure<>(new CustomerNotFound("Could not find customer " + id));
}
}
As you can see, we initialise our map of customers with three customers that we will use for our tests to make things simpler.
Now that we have some pre-populated data, we can proceed with our next test!
@Test
public void shouldReturn200WhenCustomerForAGivenIdExists() {
final ResponseEntity<Customer> response = template.getForEntity(String.format("http://localhost:%d/api/customers/3", port), Customer.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo(new Customer(3L, "Margaret McGuinness", 27));
}
In this test, we are fetching a customer by a customer ID we know is already present in our “database”. What we expect in this case is a status code in our response of 200 (OK) and a response body containing the corresponding JSON for our customer.
We mentioned before that getForEntity
has some limitations, one of them is the inability to include headers in our request. In cases where we need to pass headers in our integration test, we can use exchange
method present in TestRestTemplate
.
At the moment we support JSON format only, what if we wanted to support a different media type like XML? How would our GET request in Spring look like?

Using Exchange Method
To be able to understand how to use this method, we are going to change our example slightly. We are going to modify our GET endpoint so it can produce either JSON or XML.
To achieve this, we’ll just have to add XML to the produces
argument in our GetMapping
annotation:
@GetMapping(value = "/{id}", produces = { MediaType.APPLICATION_JSON_VALUE, MediaType.APPLICATION_XML_VALUE })
This means that, in order to test both JSON and XML responses, we’ll need to send an Accept
header in our test. Let’s see how to do this!
@Test
public void shouldReturn200WhenCustomerForAGivenIdExists() {
final HttpHeaders headers = new HttpHeaders();
headers.add("Accept", "application/json");
final ResponseEntity<Customer> response = template.exchange(String.format("http://localhost:%d/api/customers/3", port), HttpMethod.GET, new HttpEntity<>(headers), Customer.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo(new Customer(3L, "Margaret McGuinness", 27));
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_JSON);
}
You can notice how now we’re using exchange
method in our test. On top of that, we are now checking Content-Type
HTTP header to test that the response is in JSON format.
What if we want to test that we can request XML instead? This is as simple as the following, let’s add a new test:
@Test
public void shouldReturn200WhenCustomerForAGivenIdExistsInXmlFormat() {
final HttpHeaders headers = new HttpHeaders();
headers.add("Accept", MediaType.APPLICATION_XML_VALUE);
final ResponseEntity<Customer> response = template.exchange(String.format("http://localhost:%d/api/customers/3", port), HttpMethod.GET, new HttpEntity<>(headers), Customer.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
assertThat(response.getBody()).isEqualTo(new Customer(3L, "Margaret McGuinness", 27));
assertThat(response.getHeaders().getContentType()).isEqualTo(MediaType.APPLICATION_XML);
}
If we run our test, it will fail initially with the following message:
2022-12-15 07:29:21.760 WARN 48457 --- [o-auto-1-exec-1] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotWritableException: No converter for [class com.theboreddev.springbootjava.Customer] with preset Content-Type 'null']
Why is that? This is because Spring cannot find a converter to map from our object to XML format. How can we fix this then? Let’s see how!
The only thing we will have to do to fix this issue, is to add a Jackson
dependency:
implementation("com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.14.1")
This will include the right converter to support XML in our GET request in Spring Boot!
If you are interested in learning Spring in depth, we highly recommend the following books:
Conclusion
in this article we’ve learned the two ways we have to write a simple integration test for a GET request in Spring Boot. We’ve also seen how to support two different content types in our endpoints in a very easy manner.
This is all from us today! We hope you’ve found this article useful and easy to read.
Looking forward to seeing you with us very soon again! Please follow us if you want to subscribe to more of our content!
Thanks for reading us!