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:

  1. Through @AutoConfigureWebTestClient in a reactive web application where the WebHandler bean is used as the entry point into the application and mocked requests and responses are used.
  2. Through @AutoConfigureMockMvc in a servlet web application where MockMvc is used to communicate with the application through Spring MVC's dispatcher servlet. Mocked requests and responses are used.
  3. Through @SpringBootTest with 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!