![](/img/trans.png)
[英]How to exclude other @Controller from my context when testing using Spring Boot @WebMvcTest
[英]Spring MVC - Error 404 with @EnableGlobalMethodSecurity when testing Controller using @WebMvcTest
我們正在嘗試向我們的 Spring 項目Controllers
添加單元測試(順便說一句,集成測試工作正常),但是我們遇到了一個非常奇怪的行為,當我們添加帶有@EnableGlobalMethodSecurity
(帶有 JSR-250 注釋)的配置時,如果控制器實現一個接口(任何接口) Controller
不包含在 Spring 應用程序上下文中作為“請求處理程序”(我在方法上檢查了它: org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.processCandidateBean(String beanName)
),即控制器中定義的請求映射( @PostMapping
,...)沒有注冊為潛在的位置,但如果接口被刪除,那么控制器和路徑就可以毫無問題地找到。
這是我的控制器(簡化),帶有一個簡單的接口MyInterface
:
@RestController
@RequestMapping(path = "/api/customer")
@RolesAllowed({Role.Const.ADMIN})
public class CustomerController implements MyInterface {
@Override // The only method in MyInterface
public void myMethod(Object param) throws QOException {
System.out.println("Hello");
}
@PostMapping(path = {"/", ""})
public Customer create(@RequestBody Customer data) throws QOException {
return customerService.create(data);
}
}
這是測試類(如果我刪除@EnableGlobalMethodSecurity
配置類,一切正常):
@RunWith(SpringRunner.class)
@WebMvcTest(controllers = CustomerController.class)
@Import({ CustomerController.class, TestAuthConfiguration.class, TestAuthConfiguration2.class}) //, TestAuthConfiguration.class })
@ActiveProfiles({"test", "unittest"})
@WithMockUser(username = "test", authorities = { Role.Const.ADMIN })
class CustomerControllerTest {
private static final Logger LOG = LogManager.getLogger(CustomerControllerTest.class);
@EnableWebSecurity
protected static class TestAuthConfiguration extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
LOG.info("configure(HttpSecurity http) ");
http.csrf().disable().authorizeRequests().filterSecurityInterceptorOncePerRequest(true)
.antMatchers("/api/session/**").permitAll() //
.antMatchers("/api/**").authenticated() //
.anyRequest().permitAll().and() //
.addFilterBefore(new OncePerRequestFilter() {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
if (auth != null) {
LOG.info("User authenticated: {}, roles: {}", auth.getName(), auth.getAuthorities());
}
filterChain.doFilter(request, response);
}
}, BasicAuthenticationFilter.class).sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
@EnableGlobalMethodSecurity(jsr250Enabled = true, securedEnabled = false)
protected static class TestAuthConfiguration2 extends GlobalMethodSecurityConfiguration {
@Bean
public GrantedAuthorityDefaults grantedAuthorityDefaults() {
return new GrantedAuthorityDefaults(""); // Remove the ROLE_ prefix
}
}
@Autowired
MockMvc mockMvc;
@Test
void testCreate() throws Exception {
Customer bean = new Customer();
bean.setName("Test company");
when(customerServiceMock.create(bean)).thenReturn(bean);
mockMvc.perform(post("/api/customer")
.content(JsonUtils.toJSON(bean)).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.content().contentType(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.jsonPath("$.name").value("Test company"));
}
}
我不明白發生了什么,我試圖在基於注釋 JSR-250 (@RollesAllowed) 的具有安全性的控制器中找到一個單元測試示例,但我沒有發現任何有用的東西,無論如何這個問題聽起來(我)到一個錯誤,但我不確定,所以歡迎任何幫助。
庫版本:
嘗試將proxyTargetClass
屬性設置為true
。 我遇到了類似的問題,並通過添加它來解決它。
@EnableGlobalMethodSecurity(jsr250Enabled = true, proxyTargetClass = true)
此外,我建議閱讀EnableGlobalMethodSecurity
javadocs,尤其要注意proxyTargetClass
和mode
屬性。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.