【发布时间】:2018-04-06 18:46:40
【问题描述】:
我正在使用 spring MockMVC 测试弹簧架控制器。 我能够执行模拟 http 请求并验证响应。 我的设置自动连接了 WebApplicationContext:
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class MyTestClass {
@Autowired
private WebApplicationContext webAppContext;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.webAppContext)
.apply(springSecurity()).build();
}
为了告诉 MockMVC 要初始化哪些控制器并将其添加到上下文中,我有一个内部配置类:
@Configuration
@ComponentScan(
basePackages = {"com.acme"},
useDefaultFilters = false,
includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value={MyRestController.class, MyRestControllerDependency.class})
})
@EnableWebMvc
static class MyTestClassConfig implements WebMvcConfigurer {
@Bean
public MyClassRepository myClassRepository() {
return Mockito.mock(MyClassRepository.class);
}
这就像一个魅力。 MockMVC 使用加载 MyRestController 并提供由 MyRestController 映射的 url 的上下文启动容器。
现在,一些 MyRestControllers 方法被注释为:@PreAuthorize("hasAuthority('ADMINISTRATOR')"),所以下一步是测试它。
阅读 Spring 安全测试指南的集成部分
spring security and test-mockmvc
看来我应该做的就是在 MockMvcBuilders .apply() 函数调用中调用 org.springframework.security.test.web.servlet.setup.springSecurity() 。
这不起作用,我明白了:
java.lang.IllegalStateException: springSecurityFilterChain cannot be null. Ensure a Bean with the name springSecurityFilterChain implementing Filter is present or inject the Filter to be used.
我尝试将 bean 定义添加到我的内部配置类中,如下所示:
Filter springSecurityFilterChain() {
return new FilterChainProxy();
}
虽然这确实提供了一个 springSecurityFilterChain,但该实例是空的,当我运行测试时,我得到一个 NPE:
java.lang.NullPointerException
at org.springframework.security.web.FilterChainProxy.getFilters(FilterChainProxy.java:224)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
这也是可以理解的,直接实例化FilterChainProxy,确实是空的。
我怀疑我需要配置我的组件扫描以包含 Springs 的 FilterChainProxy 实例。 如果这是问题所在,我不知道我应该包括哪些课程。我试过包括所有的课程:
includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value={TenantAPI.class, TenantManager.class}),
@ComponentScan.Filter(type = FilterType.REGEX, pattern="^org\\.springframework\\.security.*")})
但这给出了相同的错误:“确保一个名为 springSecurity.. 的 Bean”,就像我在没有附加 Regex 过滤器的情况下运行测试时一样。
当我对让 MockMVC 实例化的内部类挑剔时,有谁知道如何获得 springSecurityFilterChain?
【问题讨论】:
标签: java spring unit-testing spring-mvc spring-security