您好,登錄后才能下訂單哦!
SpringSecurity中的單元測試是怎樣的,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細講解,有這方面需求的人可以來學習下,希望你能有所收獲。
今天組里的新人迷茫的問我:哥,Spring Security弄的我單元測試跑不起來,總是401,你看看咋解決。沒問題,有寫單元測試的覺悟,寫的代碼質量肯定有保證,對代碼質量重視的態度,這種忙一定要幫!
要想在單元測試中使用Spring Security,你需要在Spring Boot項目中集成:
<dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency>
這樣測試的上下文配置就能和Spring Security結合起來了,接下來教你幾招。
所有的測試都是在Spring Boot Test下進行的,也就是@SpringBootTest注解的支持下。
@WithMockUser
@WithMockUser注解可以幫我們在Spring Security安全上下文中模擬一個默認名稱為user,默認密碼為password,默認角色為USER的用戶。當你的測試方法使用了該注解后,你就能通過:
Authentication authentication = SecurityContextHolder.getContext() .getAuthentication();
獲取該模擬用戶的信息,也就“假裝”當前登錄了用戶user。當然你也可以根據需要來自定義用戶名、密碼、角色:
@SneakyThrows @Test @WithMockUser(username = "felord",password = "felord.cn",roles = {"ADMIN"}) void updatePassword() { mockMvc.perform(post("/user/update/password") .contentType(MediaType.APPLICATION_JSON) .content("{\n" + " \"newPassword\": \"12345\",\n" + " \"oldPassword\": \"12345\"\n" + "}")) .andExpect(ResultMatcher.matchAll(status().isOk())) .andDo(print()); }
當然你可以將@WithMockUser標記到整個測試類上,這樣每個測試都將使用指定該用戶。
@WithAnonymousUser
@WithAnonymousUser是用來模擬一種特殊的用戶,也被叫做匿名用戶。如果有測試匿名用戶的需要,可以直接使用該注解。其實等同于@WithMockUser(roles = {"ANONYMOUS"}),也等同于@WithMockUser(authorities = {"ROLE_ANONYMOUS"}),細心的你應該能看出來差別。
@WithUserDetails
雖然@WithMockUser是一種非常方便的方式,但可能并非在所有情況下都湊效。有時候你魔改了一些東西使得安全上下文的驗證機制發生了改變,比如你定制了UserDetails,這一類注解就不好用了。但是通過UserDetailsService 加載的用戶往往還是可靠的。于是@WithUserDetails就派上了用場。
@SneakyThrows @Test @WithUserDetails("felord") void updatePassword() { mockMvc.perform(post("/user/update/password") .contentType(MediaType.APPLICATION_JSON) .content("{\n" + " \"newPassword\": \"12345\",\n" + " \"oldPassword\": \"12345\"\n" + "}")) .andExpect(ResultMatcher.matchAll(status().isOk())) .andDo(print()); }
當我們執行單元測試時,將通過UserDetailsService 的loadUserByUsername方法查找用戶名為felord的用戶并加載到安全上下文中。
自定義注解
其實我們還可以模擬@WithMockUser
@Target({ ElementType.METHOD, ElementType.TYPE }) @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented @WithSecurityContext(factory = WithMockUserSecurityContextFactory.class) public @interface WithMockUser { String value() default "user"; String username() default ""; String[] roles() default { "USER" }; String[] authorities() default {}; String password() default "password"; @AliasFor(annotation = WithSecurityContext.class) TestExecutionEvent setupBefore() default TestExecutionEvent.TEST_METHOD; }
關鍵就在于@WithSecurityContext注解,我們只需要實現factory就行了,也就是:
public interface WithSecurityContextFactory<A extends Annotation> { SecurityContext createSecurityContext(A annotation); }
這里如法炮制就行,沒什么難度就不演示了。
今天介紹了當你的應用中集成了Spring Security時如何單元測試,我們可以使用提供的模擬用戶的注解,也可以模擬加載用戶,甚至你可以根據自己的需要來定制化。其實如果你使用了JWT的話還有種野路子,你可以在Spring MVC Mock測試中加入對應的請求頭或者參數,也能順利進行。
看完上述內容是否對您有幫助呢?如果還想對相關知識有進一步的了解或閱讀更多相關文章,請關注億速云行業資訊頻道,感謝您對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。