Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
2.8k views
in Technique[技术] by (71.8m points)

spring - testing with WebTestClient.bindToRouterFunction() is not working with kotlin - Cannot inherit from final class

I have the following test

class MyTest{
    private val s1= mockk<S1>()
    private val s2= mockk<S2>()
    private val s3= mockk<S3>()

    private val requestHandler = RequestHandler(s1, s2, s3)

    private val webTestClient = WebTestClient
        .bindToRouterFunction(RouterConfiguration(requestHandler).router())
        .build();

    @Test
    fun test1() {
        ...

        val result = webTestClient.post()
            ...
            .returnResult()

        assertNull(result.responseBody)
    }
}

and the router configuration

@Configuration
class RouterConfiguration(
    private val handler: RequestHandler,
) {
    fun router() = coRouter {
        "/api/v1".nest {
            ...
        }
    }
}

When I try to run the test I get the following error

Cannot inherit from final class
java.lang.VerifyError: Cannot inherit from final class
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:821)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:719)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:642)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:600)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at org.springframework.http.codec.support.BaseDefaultCodecs.getKotlinSerializationJsonDecoder(BaseDefaultCodecs.java:561)
    at org.springframework.http.codec.support.BaseDefaultCodecs.getObjectReaders(BaseDefaultCodecs.java:394)
    at org.springframework.http.codec.support.BaseCodecConfigurer.getReaders(BaseCodecConfigurer.java:100)
    at org.springframework.http.codec.support.DefaultServerCodecConfigurer.getReaders(DefaultServerCodecConfigurer.java:27)
    at org.springframework.web.reactive.function.server.DefaultHandlerStrategiesBuilder.build(DefaultHandlerStrategiesBuilder.java:101)
    at org.springframework.web.reactive.function.server.HandlerStrategies.withDefaults(HandlerStrategies.java:89)
    at org.springframework.test.web.reactive.server.DefaultRouterFunctionSpec.<init>(DefaultRouterFunctionSpec.java:36)
    at org.springframework.test.web.reactive.server.WebTestClient.bindToRouterFunction(WebTestClient.java:200)
    at mypgk.<init>(MyTest.kt:28)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)

I cannot figure out what the problem is and so far I haven't been able to find an answer.

Spring docs config: https://docs.spring.io/spring-framework/docs/current/reference/html/testing.html#webtestclient-fn-config

Versions

kotlin("jvm") version "1.4.21"
kotlin("plugin.spring") version "1.4.21"
kotlin("plugin.serialization") version "1.4.21"
id("org.springframework.boot") version "2.4.1"
id("io.spring.dependency-management") version "1.0.10.RELEASE"
testImplementation("io.mockk:mockk:1.10.4")
testImplementation("io.projectreactor:reactor-test:3.4.2")

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Kotlin, all the classes are implicitly marked final by default. If you want to inherit from a class, you have to explicitly add open keyword before the class declaration.

@Configuration
open class RouterConfiguration(
    private val handler: RequestHandler,
) {
    fun router() = coRouter {
        "/api/v1".nest {
            ...
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...