spockframework / spockframework/spock

Context not properly loaded with Spring Boot 3 for WebMvcTest with OpenFeign clients

Open
#1,561 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug waiting for feedback
Dominant language
Java
Stars
3.6k
Forks
483
PR merge metrics
No merged PRs in 30d

Description

Describe the bug

When migration Spring Boot to version 3 and Spock framework to version 2.4-M1 with OpenFeign client(s), tests with the WebMvcTest annotation fail to properly load the context.

Please note that the tests with @SpringBootTest are executed successfully.

Seems that the issue also happens for tests with the @DataMongoTest annotation.

To Reproduce
  • Create a Spring Boot 3 project with OpenFeign
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.springframework.cloud:spring-cloud-starter-openfeign")


testImplementation("org.springframework.boot:spring-boot-starter-test")

testImplementation("org.apache.groovy:groovy:4.0.7")
testImplementation(platform("org.spockframework:spock-bom:2.4-M1-groovy-4.0"))
testImplementation("org.spockframework:spock-core")
testImplementation("org.spockframework:spock-spring")
  • Create a dummy Rest controller that returns whatever you want
@RequestMapping("/dummy")
@RestController
class DummyController {

    @GetMapping
    fun getAllInformation() = listOf(
            Information("info1", "Great information!"),
            Information("info2", "Super important information!"),
            Information("info3", "Rather small information."),
    )

}
  • Create a dummy Feign client
@FeignClient(
   name = "google",
   url = "https://www.google.com/"
)
interface GoogleClient {
    @GetMapping("/")
    fun getHomePage(): String
}
  • Create a WebMvcTest that test the controller
@WebMvcTest([DummyController.class])
class DummyControllerSpec extends Specification {

    @Autowired
    MockMvc mockMvc


    def "get information"() {
        expect:
        mockMvc.perform(get("/dummy"))
            .andExpect(status().is2xxSuccessful())

    }
}

Minimal example with a failing test: demo.zip

Expected behavior

The test should pass

Actual behavior

The test fails with the following cause:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.cloud.openfeign.FeignClientFactory' available

(Note that the test with the @SpringBootTest annotation passes :))

Java version

17

Buildtool version

Gradle 7.6

What operating system are you using

Mac

Dependencies

Root project 'demo'

testRuntimeClasspath - Runtime classpath of compilation 'test' (target  (jvm)).
+--- org.springframework.boot:spring-boot-starter-web -> 3.0.1
|    +--- org.springframework.boot:spring-boot-starter:3.0.1
|    |    +--- org.springframework.boot:spring-boot:3.0.1
|    |    |    +--- org.springframework:spring-core:6.0.3
|    |    |    |    \--- org.springframework:spring-jcl:6.0.3
|    |    |    \--- org.springframework:spring-context:6.0.3
|    |    |         +--- org.springframework:spring-aop:6.0.3
|    |    |         |    +--- org.springframework:spring-beans:6.0.3
|    |    |         |    |    \--- org.springframework:spring-core:6.0.3 (*)
|    |    |         |    \--- org.springframework:spring-core:6.0.3 (*)
|    |    |         +--- org.springframework:spring-beans:6.0.3 (*)
|    |    |         +--- org.springframework:spring-core:6.0.3 (*)
|    |    |         \--- org.springframework:spring-expression:6.0.3
|    |    |              \--- org.springframework:spring-core:6.0.3 (*)
|    |    +--- org.springframework.boot:spring-boot-autoconfigure:3.0.1
|    |    |    \--- org.springframework.boot:spring-boot:3.0.1 (*)
|    |    +--- org.springframework.boot:spring-boot-starter-logging:3.0.1
|    |    |    +--- ch.qos.logback:logback-classic:1.4.5
|    |    |    |    +--- ch.qos.logback:logback-core:1.4.5
|    |    |    |    \--- org.slf4j:slf4j-api:2.0.4 -> 2.0.6
|    |    |    +--- org.apache.logging.log4j:log4j-to-slf4j:2.19.0
|    |    |    |    +--- org.slf4j:slf4j-api:1.7.36 -> 2.0.6
|    |    |    |    \--- org.apache.logging.log4j:log4j-api:2.19.0
|    |    |    \--- org.slf4j:jul-to-slf4j:2.0.6
|    |    |         \--- org.slf4j:slf4j-api:2.0.6
|    |    +--- jakarta.annotation:jakarta.annotation-api:2.1.1
|    |    +--- org.springframework:spring-core:6.0.3 (*)
|    |    \--- org.yaml:snakeyaml:1.33
|    +--- org.springframework.boot:spring-boot-starter-json:3.0.1
|    |    +--- org.springframework.boot:spring-boot-starter:3.0.1 (*)
|    |    +--- org.springframework:spring-web:6.0.3
|    |    |    +--- org.springframework:spring-beans:6.0.3 (*)
|    |    |    +--- org.springframework:spring-core:6.0.3 (*)
|    |    |    \--- io.micrometer:micrometer-observation:1.10.2
|    |    |         \--- io.micrometer:micrometer-commons:1.10.2
|    |    +--- com.fasterxml.jackson.core:jackson-databind:2.14.1
|    |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.14.1
|    |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1
|    |    |    |         +--- com.fasterxml.jackson.core:jackson-annotations:2.14.1 (c)
|    |    |    |         +--- com.fasterxml.jackson.core:jackson-databind:2.14.1 (c)
|    |    |    |         +--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.1 (c)
|    |    |    |         +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.1 (c)
|    |    |    |         +--- com.fasterxml.jackson.module:jackson-module-kotlin:2.14.1 (c)
|    |    |    |         +--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.14.1 (c)
|    |    |    |         \--- com.fasterxml.jackson.core:jackson-core:2.14.1 (c)
|    |    |    +--- com.fasterxml.jackson.core:jackson-core:2.14.1
|    |    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1 (*)
|    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1 (*)
|    |    +--- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.14.1
|    |    |    +--- com.fasterxml.jackson.core:jackson-core:2.14.1 (*)
|    |    |    +--- com.fasterxml.jackson.core:jackson-databind:2.14.1 (*)
|    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1 (*)
|    |    +--- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.14.1
|    |    |    +--- com.fasterxml.jackson.core:jackson-annotations:2.14.1 (*)
|    |    |    +--- com.fasterxml.jackson.core:jackson-core:2.14.1 (*)
|    |    |    +--- com.fasterxml.jackson.core:jackson-databind:2.14.1 (*)
|    |    |    \--- com.fasterxml.jackson:jackson-bom:2.14.1 (*)
|    |    \--- com.fasterxml.jackson.module:jackson-module-parameter-names:2.14.1
|    |         +--- com.fasterxml.jackson.core:jackson-core:2.14.1 (*)
|    |         +--- com.fasterxml.jackson.core:jackson-databind:2.14.1 (*)
|    |         \--- com.fasterxml.jackson:jackson-bom:2.14.1 (*)
|    +--- org.springframework.boot:spring-boot-starter-tomcat:3.0.1
|    |    +--- jakarta.annotation:jakarta.annotation-api:2.1.1
|    |    +--- org.apache.tomcat.embed:tomcat-embed-core:10.1.4
|    |    +--- org.apache.tomcat.embed:tomcat-embed-el:10.1.4
|    |    \--- org.apache.tomcat.embed:tomcat-embed-websocket:10.1.4
|    |         \--- org.apache.tomcat.embed:tomcat-embed-core:10.1.4
|    +--- org.springframework:spring-web:6.0.3 (*)
|    \--- org.springframework:spring-webmvc:6.0.3
|         +--- org.springframework:spring-aop:6.0.3 (*)
|         +--- org.springframework:spring-beans:6.0.3 (*)
|         +--- org.springframework:spring-context:6.0.3 (*)
|         +--- org.springframework:spring-core:6.0.3 (*)
|         +--- org.springframework:spring-expression:6.0.3 (*)
|         \--- org.springframework:spring-web:6.0.3 (*)
+--- com.fasterxml.jackson.module:jackson-module-kotlin -> 2.14.1
|    +--- com.fasterxml.jackson.core:jackson-databind:2.14.1 (*)
|    +--- com.fasterxml.jackson.core:jackson-annotations:2.14.1 (*)
|    +--- org.jetbrains.kotlin:kotlin-reflect:1.5.32 -> 1.7.22
|    |    \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.22
|    |         +--- org.jetbrains.kotlin:kotlin-stdlib-common:1.7.22
|    |         \--- org.jetbrains:annotations:13.0
|    \--- com.fasterxml.jackson:jackson-bom:2.14.1 (*)
+--- org.jetbrains.kotlin:kotlin-reflect:1.7.22 (*)
+--- org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.7.22
|    +--- org.jetbrains.kotlin:kotlin-stdlib:1.7.22 (*)
|    \--- org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.7.22
|         \--- org.jetbrains.kotlin:kotlin-stdlib:1.7.22 (*)
+--- org.springframework.cloud:spring-cloud-starter-openfeign -> 4.0.0
|    +--- org.springframework.cloud:spring-cloud-starter:4.0.0
|    |    +--- org.springframework.boot:spring-boot-starter:3.0.0 -> 3.0.1 (*)
|    |    +--- org.springframework.cloud:spring-cloud-context:4.0.0
|    |    |    \--- org.springframework.security:spring-security-crypto:6.0.0 -> 6.0.1
|    |    +--- org.springframework.cloud:spring-cloud-commons:4.0.0
|    |    |    \--- org.springframework.security:spring-security-crypto:6.0.0 -> 6.0.1
|    |    \--- org.springframework.security:spring-security-rsa:1.0.11.RELEASE
|    |         \--- org.bouncycastle:bcpkix-jdk15on:1.69
|    |              +--- org.bouncycastle:bcprov-jdk15on:1.69
|    |              \--- org.bouncycastle:bcutil-jdk15on:1.69
|    |                   \--- org.bouncycastle:bcprov-jdk15on:1.69
|    +--- org.springframework.cloud:spring-cloud-openfeign-core:4.0.0
|    |    +--- org.springframework.boot:spring-boot-autoconfigure:3.0.0 -> 3.0.1 (*)
|    |    +--- org.springframework.boot:spring-boot-starter-aop:3.0.0 -> 3.0.1
|    |    |    +--- org.springframework.boot:spring-boot-starter:3.0.1 (*)
|    |    |    +--- org.springframework:spring-aop:6.0.3 (*)
|    |    |    \--- org.aspectj:aspectjweaver:1.9.19
|    |    \--- io.github.openfeign.form:feign-form-spring:3.8.0
|    |         +--- io.github.openfeign.form:feign-form:3.8.0
|    |         |    \--- org.slf4j:slf4j-api:1.7.26 -> 2.0.6
|    |         +--- org.springframework:spring-web:5.1.5.RELEASE -> 6.0.3 (*)
|    |         +--- commons-fileupload:commons-fileupload:1.4
|    |         \--- org.slf4j:slf4j-api:1.7.26 -> 2.0.6
|    +--- org.springframework:spring-web:6.0.2 -> 6.0.3 (*)
|    +--- org.springframework.cloud:spring-cloud-commons:4.0.0 (*)
|    +--- io.github.openfeign:feign-core:12.1
|    \--- io.github.openfeign:feign-slf4j:12.1
|         +--- io.github.openfeign:feign-core:12.1
|         \--- org.slf4j:slf4j-api:2.0.4 -> 2.0.6
+--- org.springframework.boot:spring-boot-starter-test -> 3.0.1
|    +--- org.springframework.boot:spring-boot-starter:3.0.1 (*)
|    +--- org.springframework.boot:spring-boot-test:3.0.1
|    |    \--- org.springframework.boot:spring-boot:3.0.1 (*)
|    +--- org.springframework.boot:spring-boot-test-autoconfigure:3.0.1
|    |    +--- org.springframework.boot:spring-boot:3.0.1 (*)
|    |    +--- org.springframework.boot:spring-boot-test:3.0.1 (*)
|    |    \--- org.springframework.boot:spring-boot-autoconfigure:3.0.1 (*)
|    +--- com.jayway.jsonpath:json-path:2.7.0
|    |    +--- net.minidev:json-smart:2.4.7 -> 2.4.8
|    |    |    \--- net.minidev:accessors-smart:2.4.8
|    |    |         \--- org.ow2.asm:asm:9.1
|    |    \--- org.slf4j:slf4j-api:1.7.33 -> 2.0.6
|    +--- jakarta.xml.bind:jakarta.xml.bind-api:4.0.0
|    |    \--- jakarta.activation:jakarta.activation-api:2.1.0
|    +--- org.assertj:assertj-core:3.23.1
|    |    \--- net.bytebuddy:byte-buddy:1.12.10 -> 1.12.20
|    +--- org.hamcrest:hamcrest:2.2
|    +--- org.junit.jupiter:junit-jupiter:5.9.1
|    |    +--- org.junit:junit-bom:5.9.1
|    |    |    +--- org.junit.jupiter:junit-jupiter:5.9.1 (c)
|    |    |    +--- org.junit.jupiter:junit-jupiter-api:5.9.1 (c)
|    |    |    +--- org.junit.jupiter:junit-jupiter-engine:5.9.1 (c)
|    |    |    +--- org.junit.jupiter:junit-jupiter-params:5.9.1 (c)
|    |    |    +--- org.junit.platform:junit-platform-engine:1.9.1 (c)
|    |    |    \--- org.junit.platform:junit-platform-commons:1.9.1 (c)
|    |    +--- org.junit.jupiter:junit-jupiter-api:5.9.1
|    |    |    +--- org.junit:junit-bom:5.9.1 (*)
|    |    |    +--- org.opentest4j:opentest4j:1.2.0
|    |    |    \--- org.junit.platform:junit-platform-commons:1.9.1
|    |    |         \--- org.junit:junit-bom:5.9.1 (*)
|    |    +--- org.junit.jupiter:junit-jupiter-params:5.9.1
|    |    |    +--- org.junit:junit-bom:5.9.1 (*)
|    |    |    \--- org.junit.jupiter:junit-jupiter-api:5.9.1 (*)
|    |    \--- org.junit.jupiter:junit-jupiter-engine:5.9.1
|    |         +--- org.junit:junit-bom:5.9.1 (*)
|    |         +--- org.junit.platform:junit-platform-engine:1.9.1
|    |         |    +--- org.junit:junit-bom:5.9.1 (*)
|    |         |    +--- org.opentest4j:opentest4j:1.2.0
|    |         |    \--- org.junit.platform:junit-platform-commons:1.9.1 (*)
|    |         \--- org.junit.jupiter:junit-jupiter-api:5.9.1 (*)
|    +--- org.mockito:mockito-core:4.8.1
|    |    +--- net.bytebuddy:byte-buddy:1.12.16 -> 1.12.20
|    |    +--- net.bytebuddy:byte-buddy-agent:1.12.16 -> 1.12.20
|    |    \--- org.objenesis:objenesis:3.2
|    +--- org.mockito:mockito-junit-jupiter:4.8.1
|    |    +--- org.mockito:mockito-core:4.8.1 (*)
|    |    \--- org.junit.jupiter:junit-jupiter-api:5.9.1 (*)
|    +--- org.skyscreamer:jsonassert:1.5.1
|    |    \--- com.vaadin.external.google:android-json:0.0.20131108.vaadin1
|    +--- org.springframework:spring-core:6.0.3 (*)
|    +--- org.springframework:spring-test:6.0.3
|    |    \--- org.springframework:spring-core:6.0.3 (*)
|    \--- org.xmlunit:xmlunit-core:2.9.0
+--- org.apache.groovy:groovy:4.0.7
|    \--- org.apache.groovy:groovy-bom:4.0.7
|         \--- org.apache.groovy:groovy:4.0.7 (c)
+--- org.spockframework:spock-bom:2.4-M1-groovy-4.0
|    +--- org.spockframework:spock-core:2.4-M1-groovy-4.0 (c)
|    \--- org.spockframework:spock-spring:2.4-M1-groovy-4.0 (c)
+--- org.spockframework:spock-core -> 2.4-M1-groovy-4.0
|    +--- org.apache.groovy:groovy:4.0.6 -> 4.0.7 (*)
|    +--- org.junit:junit-bom:5.9.0 -> 5.9.1 (*)
|    +--- org.junit.platform:junit-platform-engine -> 1.9.1 (*)
|    \--- org.hamcrest:hamcrest:2.2
\--- org.spockframework:spock-spring -> 2.4-M1-groovy-4.0
     +--- org.apache.groovy:groovy:4.0.6 -> 4.0.7 (*)
     \--- org.spockframework:spock-core:2.4-M1-groovy-4.0 (*)

(c) - dependency constraint
(*) - dependencies omitted (listed previously)

A web-based, searchable dependency report is available by adding the --scan option.

Additional context

No response

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the failing example in demo.zip with the shown WebMvcTest, Spring Boot 3, Spock 2.4-M1, and OpenFeign dependencies. Compare the WebMvcTest context with the passing SpringBootTest context and investigate the missing FeignClientFactory; also check whether the reported DataMongoTest case reproduces. Done means the controller test loads and passes without weakening the test slice.

Written by the indexing model from the issue text.

Assessment

Tech stack
groovy, java, kotlin, spring-boot
Domain
backend, testing
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.