Spring boot 版本更新到 3.2.2 后,Spring boot 集成测试无法正常工作

问题描述 投票:0回答:1

我们使用 String boot 测试框架编写了一个集成测试,并利用

TestRestTemplate
在测试上下文初始化后进行 HTTP 调用。

这在 String boot 版本 3.1.2 中按预期工作

更新 Spring Boot 版本 3.2.2 后,相同的测试不起作用

错误:

ava.lang.IllegalStateException: Failed to load ApplicationContext for [WebMergedContextConfiguration@42cb8174 testClass = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@73a0f2b, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@687e6293, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@7e4579c7, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@769bd849, org.springframework.boot.test.context.SpringBootTestAnnotation@804fcdb7], resourceBasePath = "src/main/webapp", contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
    at com.teketik.test.mockinbean.MockInBeanTestExecutionListener.beforeTestClass(MockInBeanTestExecutionListener.java:58)
    at org.springframework.test.context.TestContextManager.beforeTestClass(TestContextManager.java:220)
    at org.springframework.test.context.junit.jupiter.SpringExtension.beforeAll(SpringExtension.java:133)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$12(ClassBasedTestDescriptor.java:396)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:396)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:212)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:85)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:148)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79)
    at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:62)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
    at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
    at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
    at jdk.proxy2/jdk.proxy2.$Proxy5.stop(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker$3.run(TestWorker.java:193)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
    at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:113)
    at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:65)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
    at worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
    Suppressed: java.lang.NullPointerException: Cannot invoke "java.util.LinkedList.forEach(java.util.function.Consumer)" because the return value of "org.springframework.test.context.TestContext.getAttribute(String)" is null
        at com.teketik.test.mockinbean.MockInBeanTestExecutionListener.afterTestClass(MockInBeanTestExecutionListener.java:122)
        at org.springframework.test.context.TestContextManager.afterTestClass(TestContextManager.java:538)
        at org.springframework.test.context.junit.jupiter.SpringExtension.afterAll(SpringExtension.java:144)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$18(ClassBasedTestDescriptor.java:462)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeAfterAllCallbacks$19(ClassBasedTestDescriptor.java:462)
        at org.junit.platform.commons.util.CollectionUtils.forEachInReverseOrder(CollectionUtils.java:217)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeAfterAllCallbacks(ClassBasedTestDescriptor.java:461)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:236)
        at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.after(ClassBasedTestDescriptor.java:85)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:161)
        at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
        at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:161)
        ... 49 more
Caused by: java.lang.IllegalStateException: java.lang.IncompatibleClassChangeError: class org.eclipse.jetty.http2.server.HttpChannelOverHTTP2 has interface org.eclipse.jetty.server.HttpChannel as super class
    at org.springframework.boot.SpringApplication.handleRunFailure(SpringApplication.java:825)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:344)
    at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
    at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1454)
    at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:552)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
    ... 61 more
Caused by: java.lang.IncompatibleClassChangeError: class org.eclipse.jetty.http2.server.HttpChannelOverHTTP2 has interface org.eclipse.jetty.server.HttpChannel as super class
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520)
    at org.eclipse.jetty.http2.server.AbstractHTTP2ServerConnectionFactory.<init>(AbstractHTTP2ServerConnectionFactory.java:82)
    at org.eclipse.jetty.http2.server.HTTP2ServerConnectionFactory.<init>(HTTP2ServerConnectionFactory.java:53)
    at org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory.<init>(HTTP2CServerConnectionFactory.java:53)
    at org.eclipse.jetty.http2.server.HTTP2CServerConnectionFactory.<init>(HTTP2CServerConnectionFactory.java:48)
    at com.github.tomakehurst.wiremock.jetty11.Jetty11HttpServer.createHttpConnector(Jetty11HttpServer.java:53)
    at com.github.tomakehurst.wiremock.jetty.JettyHttpServer.<init>(JettyHttpServer.java:89)
    at com.github.tomakehurst.wiremock.jetty11.Jetty11HttpServer.<init>(Jetty11HttpServer.java:44)
    at com.github.tomakehurst.wiremock.jetty.JettyHttpServerFactory.buildHttpServer(JettyHttpServerFactory.java:31)
    at com.github.tomakehurst.wiremock.WireMockServer.<init>(WireMockServer.java:81)
    at org.eclipse.tractusx.managedidentitywallets.config.TestContextInitializer.initialize(TestContextInitializer.java:160)
    at org.springframework.boot.SpringApplication.applyInitializers(SpringApplication.java:627)
    at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:400)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:333)
    ... 70 more


构建.gradle

plugins {
    id 'java'
    id 'org.springframework.boot' version "${springBootVersion}"
    id 'io.spring.dependency-management' version "${springDependencyVersion}"
    id "jacoco"
    id 'project-report'
    id "org.sonarqube" version "4.4.1.3373"

}


group = "${groupName}"
version = "${applicationVersion}"
sourceCompatibility = JavaVersion.VERSION_17

sonar {
    properties {
        property "sonar.projectName", "cofinity-x-managed-identity-wallet-core"
        property "sonar.projectKey", "Cofinity-X_cofinity-x-managed-identity-wallet-core"
        property "sonar.organization", "cofinity-x"
        property "sonar.host.url", "https://sonarcloud.io"
    }
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenLocal()
    mavenCentral()
    maven {
        url = uri("https://repo.danubetech.com/repository/maven-public")
    }
}

ext {

}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.security:spring-security-oauth2-resource-server'
    implementation 'org.springframework.security:spring-security-oauth2-jose'
    implementation 'org.springframework.cloud:spring-cloud-starter-openfeign'
    implementation "org.springdoc:springdoc-openapi-starter-common:${openApiVersion}"
    implementation "org.springdoc:springdoc-openapi-starter-webmvc-ui:${openApiVersion}"
    implementation 'org.liquibase:liquibase-core'
    testImplementation 'org.wiremock:wiremock:3.3.1'
    testImplementation 'org.projectlombok:lombok:1.18.30'
    runtimeOnly 'org.postgresql:postgresql'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testAnnotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation "org.testcontainers:testcontainers"
    testImplementation 'com.h2database:h2:2.2.220'
    testImplementation "org.testcontainers:junit-jupiter"
    testImplementation group: 'com.github.dasniko', name: 'testcontainers-keycloak', version: '2.5.0'
    testImplementation group: 'org.mockito', name: 'mockito-inline', version: '5.2.0'
    testImplementation group: 'org.json', name: 'json', version: '20230227'
    testImplementation group: 'com.teketik', name: 'mock-in-bean', version: 'boot2-v1.5.2'

}

dependencyManagement {
    imports {
        mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
        mavenBom("org.testcontainers:testcontainers-bom:${testContainerVersion}")
    }
}

tasks.named('test') {
    useJUnitPlatform()
}

build {
    archivesBaseName = "miw"
    version = "latest"
}

bootJar {
    metaInf {
        from 'DEPENDENCIES'
        from 'SECURITY.md'
        from 'NOTICE.md'
        from 'LICENSE'
    }
}

test {
    finalizedBy jacocoTestReport
    testLogging {
        events("passed", "skipped", "failed")
    }
}

htmlDependencyReport {
    projects = project.allprojects
}

jacocoTestReport {
    dependsOn test

}

jacoco {
    toolVersion = "${jacocoVersion}"

}


jacocoTestCoverageVerification {
    violationRules {
        rule {
            limit {
                minimum = 0.80
            }
        }
    }
}

check.dependsOn jacocoTestCoverageVerification

gradle.属性


springCloudVersion=2023.0.0
testContainerVersion=1.18.3
jacocoVersion=0.8.9
springBootVersion=3.2.2
springDependencyVersion=1.1.4

我本地机器上的Java版本:

openjdk 17.0.2 2022-01-18
OpenJDK Runtime Environment (build 17.0.2+8-86)
OpenJDK 64-Bit Server VM (build 17.0.2+8-86, mixed mode, sharing)
java spring spring-boot wiremock
1个回答
0
投票

问题是因为

wiremock

问题: springboot3.2使用的是jetty 12,以及wiremock jetty11。

解决方案:使用wiremock-standalone作为依赖

testImplementation 'org.wiremock:wiremock-standalone:3.3.1'

参考:https://github.com/wiremock/wiremock/issues/2395

© www.soinside.com 2019 - 2024. All rights reserved.