【Spring】SpringSecurityを使ってるアプリで、Controllerのテストを行う
#SpringFramework #Java #JUnit
ちょっと詰まったので備忘を兼ねてメモ。
Spring Web MVC + Spring Securityを使ったアプリケーションで、Controllerの単体テストを行う時の定義とかお作法とか。
■コントローラ
code:HelloController.java
@RestController
public class HelloController {
@PreAuthorize("hasAuthority('ADMIN')")
@GetMapping("/hello")
public String sayHello() {
return "Hello World";
}
}
こんな感じでメソッドセキュリティを用いて、ADMINの権限が付与されているユーザのみが /helloを呼び出すことができる。
■テストクラス
code:HelloControllerTest.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloControllerTest {
@Autowired
private WebApplicationContext context;
private MockMvc mockMvc;
@Before
public void before() {
this.mockMvc = MockMvcBuilders
.webAppContextSetup(this.context)
.apply(SecurityMockMvcConfigurer.springSecurity())
.build();
}
@Test
@WithMockUser(authorities = {"ADMIN"})
public void test() {
...
}
}
@WithMockUser を用いることで、認証済みユーザのモックを生成してくれる。
なお、@WithMockUserはクラス or メソッドに注釈することができ、優先度は メソッド > クラス となる。
各プロパティは以下の通り。
authorities:ユーザの権限
password:ユーザのパスワード
roles:ユーザのロール
username:ユーザ名(value側に指定した場合は不要)
value:ユーザ名(username側に指定した場合は不要)
(2019年4月6日 追記)
@WithMockUserを使ってもよいが、基本的にユーザ情報は独自に拡張したものを利用することが多いと思う。
その場合は、別途アノテーションを独自で作成する必要がある。
https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#test-method-withsecuritycontext
上記に記載されている通り、WithSecurityContextFactoryを実装したクラスと、それに対応するアノテーションを作成する。(何をどうすればいいかはリンク先の資料に書いてあるので省略)
参考サイト
Spring Security for Spring Boot Integration Tests