java.lang.IllegalStateException(未找到方法):使用自定义过滤器在一次测试中多次调用 MockMvc.perform
java.lang.IllegalStateException(Method not found): Calling MockMvc.perform multiple time in one test with customized Filter
为了在带有 @AuthenticationPrincipal
注释的 spring 安全保护 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()))
}
}
当 运行 测试时,java.IllegalStateException
抛出第二个 perform
赞:
Method not found: BaseSpringIntegrationTest$mockSpringSecurityFilter.getFilters(org.springframework.mock.web.MockHttpServletRequest)
java.lang.IllegalStateException: Method not found: BaseSpringIntegrationTest$mockSpringSecurityFilter.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){}
为了在带有 @AuthenticationPrincipal
注释的 spring 安全保护 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()))
}
}
当 运行 测试时,java.IllegalStateException
抛出第二个 perform
赞:
Method not found: BaseSpringIntegrationTest$mockSpringSecurityFilter.getFilters(org.springframework.mock.web.MockHttpServletRequest)
java.lang.IllegalStateException: Method not found: BaseSpringIntegrationTest$mockSpringSecurityFilter.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){}