springboot對shiro進行mock單元測試
阿新 • • 發佈:2018-11-19
環境:junit-5、Spring5.0.x、Spring Boot 2.0.x
以下是用來許可權測試的介面:
@ApiOperation("[可接入]分頁查詢管理員") @ApiResponses({@ApiResponse(code = 200, message = "訪問成功", response = APIResponse.class), @ApiResponse(code = 201, message = "data", response = BackPageManagerDTO.class)}) @ApiImplicitParams({@ApiImplicitParam(name = "page", value = "頁碼", required = true, defaultValue = "1"), @ApiImplicitParam(name = "size", value = "數目", required = true, defaultValue = "15")}) @GetMapping("/page") @RequiresPermissions(PermissionConst.MANAGER) APIResponse page(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "15") Integer size);
百度shiro的單元測試,發現沒有一個是可以在測試時以指定Subject執行的,最接近的是ThreadCOntext.bind(securityManager),但這只是綁定了所有SecurityManger,而SecurityManager下還有很多Subject,將ThreadCOntext.bind(securityManager)改為ThreadCOntext.bind(subject)即可以指定subject身份去測試介面。個人案例如下:
@SpringBootTest(classes = BackendApplication.class) @AutoConfigureMockMvc @SpringJUnitConfig @PropertySource(value = "classpath:jdbc.properties", encoding = "UTF-8") @ImportResource(locations = {"classpath:*-config.xml"}) @WebAppConfiguration class ManagerTest { @Resource private BackManagerController managerController; @Resource private SecurityManager securityManager; @Resource private WebApplicationContext webApplicationContext; @Resource private SessionDAO sessionDAO; private Subject subject; private MockMvc mockMvc; private MockHttpServletRequest mockHttpServletRequest; private MockHttpServletResponse mockHttpServletResponse; private void login(String username, String password) { subject = new WebSubject.Builder(mockHttpServletRequest, mockHttpServletResponse) .buildWebSubject(); UsernamePasswordToken token = new UsernamePasswordToken(username, password, true); subject.login(token); ThreadContext.bind(subject); } @BeforeEach void before() { mockHttpServletRequest = new MockHttpServletRequest(webApplicationContext.getServletContext()); mockHttpServletResponse = new MockHttpServletResponse(); MockHttpSession mockHttpSession = new MockHttpSession(webApplicationContext.getServletContext()); mockHttpServletRequest.setSession(mockHttpSession); SecurityUtils.setSecurityManager(securityManager); mockMvc = MockMvcBuilders .webAppContextSetup(webApplicationContext) .build(); login("test112", "111111"); } @Test void page() throws Exception { System.out.println("-------------shiro基本許可權測試-------------"); System.out.println("init page result:" + mockMvc.perform(MockMvcRequestBuilders.get("/back/manager/page?page=1&size=15")) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn() .getResponse() .getContentAsString()); System.err.println("all session id:" + sessionDAO.getActiveSessions().stream() .map(Session::getId) .reduce((x, y) -> x + "," + y) .orElse("")); System.out.println("-------------測試同一使用者異地登入將另一session踢出,該過程在CredentialsMatcher進行處理-------------"); login("test112", "111111"); System.out.println("user login again page result:" + mockMvc.perform(MockMvcRequestBuilders.get("/back/manager/page?page=1&size=15")) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn() .getResponse() .getContentAsString()); System.err.println("all session id:" + sessionDAO.getActiveSessions().stream() .map(Session::getId) .reduce((x, y) -> x + "," + y) .orElse("")); System.out.println("-------------測試登出後許可權-------------"); subject.logout(); System.out.println("logout page result:" + mockMvc.perform(MockMvcRequestBuilders.get("/back/manager/page?page=1&size=15")) .andExpect(MockMvcResultMatchers.status().isOk()) .andReturn() .getResponse() .getContentAsString()); } }
測試結果圖(以下測試結果分別是測shiro登入後許可權處理、同號只能單處登入、登出後許可權處理功能的結果):