简体   繁体   中英

Mockk - ClassCastException when mocking final class that implements multiple interfaces

I'm trying to use a mock of this Java class:

public final class HttpSecurity extends
        AbstractConfiguredSecurityBuilder<DefaultSecurityFilterChain, HttpSecurity>
        implements SecurityBuilder<DefaultSecurityFilterChain>,
        HttpSecurityBuilder<HttpSecurity>

So I've created a mock like so:

private val httpSecurity: HttpSecurity = mockk(relaxed = true)

in order to test this bit of Java code:

  protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable().
                headers().frameOptions().disable().and()
                .formLogin().loginPage("/login").permitAll()....etc

and I'm getting the following error when I try and use it

java.lang.ClassCastException: org.springframework.security.config.annotation.web.HttpSecurityBuilder$Subclass2 cannot be cast to org.springframework.security.config.annotation.web.builders.HttpSecurity

Test class here:

package com.whatever

import io.mockk.mockk
import io.mockk.mockkClass
import org.junit.jupiter.api.Test

import org.springframework.core.env.Environment
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.config.annotation.web.builders.HttpSecurity

internal class SecurityConfigTest {


    private val authManager: AuthenticationManager = mockk()
    val env : Environment = mockk()
    private val httpSecurity: HttpSecurity = mockk(relaxed = true)

    val securityConfig : SecurityConfig = SecurityConfig(authManager,env)

    @Test
    fun configure() {
        securityConfig.configure(httpSecurity)
    }
}

Any ideas how to fix this ?

The problem here is that the template argument type is erased and not possible to recover. The only solution is to specify mock directly so that reified type will capture actual class:

val mockk = mockk<HttpSecurity>(relaxed = true)
val csrf = mockk.csrf()
every { csrf.disable() } returns mockk(relaxed = true)
val disable = csrf.disable()
disable.headers()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM