Hello,
I want to use the @SpringBootTest annotation in my custom meta-annotation @SpringBootTestGvl like this:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootTest
@AutoConfigureWebTestClient // injection will fail with and without this annotation. this setting does not make any difference
public @interface SpringBootTestGvl {
}
in my integration test like
@SpringBootTestGvl
class ApplicationIT {
@Autowired
private WebTestClient webTestClient; // injection fails
...
Test method parameter injection will also fail (like the field injection on test class)
void myTestMethod(@Autowired WebTestClient webTestClient) {
...
}
The @SpringBootTestGvl is working fine as long as the integration test does not inject/require a WebTestClient.
Is this a bug or a missing feature what I try to achieve ?
Comment From: wilkinsona
It's hard to say without some more information. You could, for example, be missing the necessary dependencies for WebTestClient to be auto-configurable or your application may not have a WebHandler bean available.
With a dependency on spring-boot-starter-webflux, this works for me:
package com.example.gh_43297;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.web.reactive.server.WebTestClient;
@SpringBootTestGvl
class Gh43297ApplicationTests {
@Autowired
WebTestClient webTestClient;
@Test
void contextLoads() {
assertThat(this.webTestClient).isNotNull();
}
}
@SpringBootTestGvl is as you showed above.
If the above doesn't help and you'd like us to spend some more time investigating, please spend some time providing a complete yet minimal sample that reproduces the problem. You can share it with us by pushing it to a separate repository on GitHub or by zipping it up and attaching it to this issue.
Comment From: rfelgent
thank you very much @wilkinsona for your investigation , I will provide a minimal working example by tomorrow
Comment From: rfelgent
Hi @wilkinsona ,
here is my example project: https://github.com/gvl-mbh/gh-43297
Building the project with ./mvnw clean verify should fail on your machine, too.
I made following observatin: when using a real web environment instead of mocked web environment the test runs successfully.
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
// the WebTestClient is available in IT class
//@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
// the WebTestClient is *not* available in IT class
@SpringBootTest
public @interface SpringBootTestGvl {
}
Comment From: wilkinsona
Thanks for the example. The behavior that you're seeing is expected and is the same if you use @SpringBootTest and @AutoConfigureWebTestClient directly rather than as meta-annotations.
There are few different ways in which @WebTestClient can be available to tests:
- Through
@AutoConfigureWebTestClientin a reactive web application where theWebHandlerbean is used as the entry point into the application and mocked requests and responses are used. - Through
@AutoConfigureMockMvcin a servlet web application whereMockMvcis used to communicate with the application through Spring MVC's dispatcher servlet. Mocked requests and responses are used. - Through
@SpringBootTestwith a random or defined port. Communication with the app is over HTTP uses real requests and responses.
Your use of @AutoConfigureWebTestClient did not work as you're building a servlet web application. This means that there's no WebHandler bean so WebTestClient cannot communicate directly with the application. If you switched to a reactive application (a dependency on spring-boot-starter-webflux and no dependency on spring-boot-starter-web), @AutoConfigureWebTestClient will work.
To stick with a servlet-based web application, replace @AutoConfigureWebTestClient with @AutoConfigureMockMvc and a WebTestClient that delegates to MockMvc will be auto-configured.
You've already observed the third option working when you configured the web environment to use a random port. A defined port will also work should you wish.
Options 1 and 2 are described in https://docs.spring.io/spring-boot/reference/testing/spring-boot-applications.html#testing.spring-boot-applications.with-mock-environment. The third option is described in https://docs.spring.io/spring-boot/reference/testing/spring-boot-applications.html#testing.spring-boot-applications.with-running-server.
I'm going to close this now as things seem to be working as expected and documented and I haven't been able to reproduce any problems when using meta-annotations rather than annotating the test class directly. If you believe I've missed something, please let us know and we can take another look.
Comment From: rfelgent
Hi @wilkinsona ,
thanks for your analysis and summarizing the options making the WebTestClient available in an IT
I should have read the documentation more carefully
Thx again!