简体   繁体   English

Spring 启动 WebMvcTest,这里是什么导致 IllegalArgumentException?

[英]Spring Boot WebMvcTest, what is causing IllegalArgumentException here?

i have the following WebMvcTest in a Spring Boot project.我在 Spring 引导项目中有以下 WebMvcTest。 I have HTTPS and JWT token authentication enabled.我启用了 HTTPS 和 JWT 令牌身份验证。 The test worked before i had HTTPS and JWT, but after adding them it gives an IllegalArgumentException.该测试在我有 HTTPS 和 JWT 之前有效,但在添加它们之后它给出了 IllegalArgumentException。

I can't for the life of me figure out where the exception is coming from.我一生都无法弄清楚异常来自哪里。 Can anyone point me in the right direction?谁能指出我正确的方向?

Test class:测试 class:

@RunWith(SpringRunner.class)
@WebMvcTest(controllers = ActionController.class)
public class ActionControllerTests {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private ActionService service;

    @MockBean
    private UserDetailsService userDetailsService;

    @MockBean
    private JwtRequestFilter jwtRequestFilter;

    @Test
    @WithMockUser
    public void testGetActions_returns_result_from_service() throws Exception {
        int actionId = 1;
        Action action = new Action();
        action.setId(actionId);
        List<Action> actionsList = Arrays.asList(action);

        given(service.getActions()).willReturn(actionsList);

        mvc.perform(get("/actions").secure(true)
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$", hasSize(1)))
                .andExpect(jsonPath("$[0].id", Matchers.is(actionId)));
    }
}

It throws this IllegalArgumentException:它抛出这个 IllegalArgumentException:

java.lang.IllegalArgumentException: Attribute name must not be null

    at org.springframework.util.Assert.notNull(Assert.java:198)
    at org.springframework.mock.web.MockHttpServletRequest.setAttribute(MockHttpServletRequest.java:756)
    at javax.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:257)
    at javax.servlet.ServletRequestWrapper.setAttribute(ServletRequestWrapper.java:257)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.web.filter.CorsFilter.doFilterInternal(CorsFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.header.HeaderWriterFilter.doHeadersAfter(HeaderWriterFilter.java:92)
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:77)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.access.channel.ChannelProcessingFilter.doFilter(ChannelProcessingFilter.java:157)
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:134)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:183)
    at nl.kars.lms.controller.ActionControllerTests.testGetActions_returns_result_from_service(ActionControllerTests.java:57)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:74)
    at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

Thanks a bunch.谢谢一堆。

Mocking jwtRequestFilter causes Spring to attempt to use the mock as an actual filter. Mocking jwtRequestFilter导致 Spring 尝试将模拟用作实际过滤器。 This is what is causing the exception.这就是导致异常的原因。

Kumar V's answer of adding @AutoConfigureMockMvc(addFilters = false) is only a workaround because it disables the JwtRequestFilter , which is not good practice in this case. Kumar V添加@AutoConfigureMockMvc(addFilters = false)的答案只是一种解决方法,因为它禁用了JwtRequestFilter ,在这种情况下这不是一个好习惯。

You have 2 options:您有 2 个选项:

  1. Remove the mocked JwtRequestFilter entirely, or完全删除模拟的JwtRequestFilter ,或
  2. Configure all necessary behavior into the mocked jwtRequestFilter with given().willReturn() ;使用given().willReturn()将所有必要的行为配置到模拟的jwtRequestFilter中;

I recommend option 1 in this scenario, unless there is a specific reason why you do not want to use the real JwtRequestFilter .在这种情况下,我推荐选项 1,除非有特定原因您不想使用真正的JwtRequestFilter

Looks like some internal filters (related to security) kicked in for this request.看起来一些内部过滤器(与安全相关)为此请求启动。

If your test case is not intended to test anything related to filters, we can disable all the filters using @AutoConfigureMockMvc(addFilters = false) for your test case如果您的测试用例不打算测试与过滤器相关的任何内容,我们可以为您的测试用例使用@AutoConfigureMockMvc(addFilters = false)禁用所有过滤器

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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