我正在使用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')")因此,下一步是对其进行测试。
@PreAuthorize("hasAuthority('ADMINISTRATOR')")
阅读Spring安全测试指南spring security和test-mockmvc的Integration部分, 似乎我应该做的就是在MockMvcBuilders .apply()函数调用中调用org.springframework.security.test.web.servlet.setup.springSecurity()。
.apply()
这不起作用,我得到:
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,它确实是空的。
我怀疑我需要配置组件扫描以包括Spring的FilterChainProxy实例。 如果 那是问题,我不知道应该包括哪些类。我尝试过包括所有课程:
includeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value={TenantAPI.class, TenantManager.class}), @ComponentScan.Filter(type = FilterType.REGEX, pattern="^org\\.springframework\\.security.*")})
但这给出了相同的错误:“在没有附加Regex筛选器的情况下运行测试时,出现“确保名称为springSecurity ..的Bean”。
当我对让MockMVC实例化的内部类挑剔时,有人知道我如何获得springSecurityFilterChain?
我认为您必须在@Configuration某个可以延伸的地方上课WebSecurityConfigurerAdapter?这是设置Spring安全性所需的配置。
@Configuration
WebSecurityConfigurerAdapter
您需要在测试配置的组件扫描中包括此类。