I have a REST (spring-hateoas) server that I'd like to test with a JUnit test. Therefore I am using an autoinjected TestRestTemplate
.
But how do I now add some more configuration to this pre configured TestRestTemplate? I need to configure the rootURI and add interceptors.
Thisi s my JUnit Test class:
@RunWith(SpringRunner.class)
@ActiveProfiles("test")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class RestEndpointTests {
private Logger log = LoggerFactory.getLogger(this.getClass());
@LocalServerPort
int localServerPort;
@Value(value = "${spring.data.rest.base-path}") // nice trick to get basePath from application.properties
String basePath;
@Autowired
TestRestTemplate client; // how to configure client?
[... here are my @Test methods that use client ...]
}
The documentation sais that a static @TestConfiguration
class can be used. But inside that static class I cannot access localServerPort
or basePath
:
@TestConfiguration
static class Config {
@Bean
public RestTemplateBuilder restTemplateBuilder() {
String rootUri = "http://localhost:"+localServerPort+basePath; // <=== DOES NOT WORK
log.trace("Creating and configuring RestTemplate for "+rootUri);
return new RestTemplateBuilder()
.basicAuthorization(TestFixtures.USER1_EMAIL, TestFixtures.USER1_PWD)
.errorHandler(new LiquidoTestErrorHandler())
.requestFactory(new HttpComponentsClientHttpRequestFactory())
.additionalInterceptors(new LogRequestInterceptor())
.rootUri(rootUri);
}
}
My most important question: Why doesn't TestRestTemplate
take spring.data.rest.base-path
from application.properties
into account in the first place? Isn't the idea of beeing complete preconfigured, the whole use case of this wrapper class?
The doc sais
If you are using the @SpringBootTest annotation, a TestRestTemplate is automatically available and can be @Autowired into you test. If you need customizations (for example to adding additional message converters) use a RestTemplateBuilder @Bean.
How does that look like in a complete Java code example?
I know this is an old question, and you have probably found another solution for this by now. But I'm answering anyway for others stumbling on it like I did. I had a similar problem and ended up using @PostConstruct in my test class for constructing a TestRestTemplate configured to my liking instead of using @TestConfiguration.
@RunWith(SpringJUnit4ClassRunner.class)
@EnableAutoConfiguration
@SpringBootTest(classes = {BackendApplication.class}, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MyCookieClientTest {
@LocalServerPort
int localPort;
@Autowired
RestTemplateBuilder restTemplateBuilder;
private TestRestTemplate template;
@PostConstruct
public void initialize() {
RestTemplate customTemplate = restTemplateBuilder
.rootUri("http://localhost:"+localPort)
....
.build();
this.template = new TestRestTemplate(customTemplate,
null, null, //I don't use basic auth, if you do you can set user, pass here
HttpClientOption.ENABLE_COOKIES); // I needed cookie support in this particular test, you may not have this need
}
}
In order to configure your TestRestTemplate, the official documentation suggests you to use the TestRestTemplate, as shown in the example below (for example, to add a Basic Authentication):
public class YourEndpointClassTest {
private static final Logger logger = LoggerFactory.getLogger(YourEndpointClassTest.class);
private static final String BASE_URL = "/your/base/url";
@TestConfiguration
static class TestRestTemplateAuthenticationConfiguration {
@Value("${spring.security.user.name}")
private String userName;
@Value("${spring.security.user.password}")
private String password;
@Bean
public RestTemplateBuilder restTemplateBuilder() {
return new RestTemplateBuilder().basicAuthentication(userName, password);
}
}
@Autowired
private TestRestTemplate restTemplate;
//here add your tests...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With