spring - java.lang.IllegalStateException(未找到方法) : Calling MockMvc. 使用自定义 Filter 在一次测试中执行多次

标签 spring spring-boot kotlin spring-security spring-test

为了使用 @AuthenticationPrincipal 注释在 Spring Security protected REST api 中检索 UserDetails 对象,我在 MockMvc 对象中添加了一个自定义过滤器,例如喜欢:

@ExtendWith(SpringExtension::class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class BaseSpringIntegrationTest {
    @Autowired
    private lateinit var context: WebApplicationContext

    lateinit var mockMvc: MockMvc

    val mockUser = UsernamePasswordAuthenticationToken(MyUserDetails("MOCK_USER"), "MOCK_PASSWORD",  listOf(SimpleGrantedAuthority("MOCKED_ROLE")))

    @PostConstruct
    fun init() {
        mockMvc = MockMvcBuilders
            .webAppContextSetup(context)
            .apply<DefaultMockMvcBuilder>(springSecurity(mockSpringSecurityFilter))
            .build()
    }

    private val mockSpringSecurityFilter = object: Filter {
        override fun doFilter(req: ServletRequest, res: ServletResponse, chain: FilterChain) {
            with ((req as HttpServletRequest).userPrincipal) {
                if (this != null)
                    SecurityContextHolder.getContext().authentication = this as Authentication
                }
            chain.doFilter(req, res)
        }

        override fun destroy() {
            SecurityContextHolder.clearContext()
        }
    }
}

然后,我尝试在一些测试中调用 mockMvc 对象两次,如下所示:

class DummyTests: BaseSpringIntegrationTest() {
    @Test
    fun dummyTest() {
        mockMvc.perform(MockMvcRequestBuilders.post("<MY_URL>").principal(mockUser))
            .andExpect(MockMvcResultMatchers.status().`is`(HttpStatus.OK.value()))

        mockMvc.perform(MockMvcRequestBuilders.post("<ANOTHER_URL>").principal(mockUser))
            .andExpect(MockMvcResultMatchers.status().`is`(HttpStatus.OK.value()))
    }
}

运行测试时,第二个perform会抛出java.IllegalStateException:

Method not found: BaseSpringIntegrationTest$mockSpringSecurityFilter$1.getFilters(org.springframework.mock.web.MockHttpServletRequest)
java.lang.IllegalStateException: Method not found: BaseSpringIntegrationTest$mockSpringSecurityFilter$1.getFilters(org.springframework.mock.web.MockHttpServletRequest)
    at org.springframework.util.ReflectionUtils.handleReflectionException(ReflectionUtils.java:104)
    at org.springframework.test.util.ReflectionTestUtils.invokeMethod(ReflectionTestUtils.java:502)
    at org.springframework.test.util.ReflectionTestUtils.invokeMethod(ReflectionTestUtils.java:427)
    at org.springframework.security.test.web.support.WebTestUtils.findFilter(WebTestUtils.java:121)
    at org.springframework.security.test.web.support.WebTestUtils.getSecurityContextRepository(WebTestUtils.java:63)
    at org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors$SecurityContextRequestPostProcessorSupport.save(SecurityMockMvcRequestPostProcessors.java:725)
    at org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors$TestSecurityContextHolderPostProcessor.postProcessRequest(SecurityMockMvcRequestPostProcessors.java:805)
    at org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder.postProcessRequest(MockHttpServletRequestBuilder.java:831)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:173)

如果测试中只有一个 perform 调用,则一切正常。

有人可以帮忙解决这个问题吗?

最佳答案

我遇到了同样的问题,我通过将以下方法添加到我的 MockSpringSecurityFilter 来解决它

public void getFilters(MockHttpServletRequest mockHttpServletRequest){}

关于spring - java.lang.IllegalStateException(未找到方法) : Calling MockMvc. 使用自定义 Filter 在一次测试中执行多次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66745250/

相关文章:

kotlin - 我们需要在 kotlin 中初始化可为空的字段吗?

java - Spring MVC- REST POST - 错误请求 400

java - 无法执行目标 org.springframework.boot :spring-boot-maven-plugin:1. 5.6.RELEASE

Spring jsp 形式的 Eclipse 警告 “List is a raw type”

java - 使用 docker-compose 连接 mongodb 容器的 Spring Boot 容器出现 503 错误代码

android - 是否可以将使用 native react 制作的 GUI 与 native 代码 (kotlin) 中的实用方法相结合?

java - Spring MVC 应用程序中的 CommandLineRunner 功能

ubuntu - Spring Boot 服务无法识别

java - POST 后返回具有 @ManyToOne 关系的已保存实体

android - 通过适配器更改RecyclerView项目图标