시큐리티 옵션 활성화되면 인증된 사용자만 API 호출 가능함
기존의 API 테스트 코드들이 모두 인증 권한 없음 -> 테스트 코드마다 인증한 사용자가 호출한 것처럼 작동하게 수정
Gradle에서 전체 테스트 수행하는 것에서 오류남
-> Test에서 오른쪽 마우스, 전체 테스트 실행으로 하면 됨
1. CustomOAuth2UserService 찾을 수 없음
CustomOAuth2UserService를 생성하는 데 필요한 소셜 로그인 관련 설정값들이 없어서 발생함
src/test에 application.properties가 없으면 src/main에 있는 설정을 그대로 가져옴
이때 application-oauth.properties 설정은 가져오지 않음 (application.properties만 가져오기 때문에)
spring.jpa.show_sql=true
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.h2.console.enabled=true
spring.session.store-type=jdbc
# Test OAuth
spring.security.oauth2.client.registration.google.client-id=test
spring.security.oauth2.client.registration.google.client-secret=test
spring.security.oauth2.client.registration.google.scope=profile,email
#가짜 설정값을 등록함
2. 302 Status Code
스프링 시큐리티 설정 때문에 인증되지 않은 사용자의 요청은 이동시킴
-> 임의로 인증된 사용자를 추가해 API만 테스트 가능하게 수정
build.gradle
testCompile('org.springframework.security:spring-security-test')
PostApiControllerTest 수정
@Test
@WithMockUser(roles = "USER")
public void PostsRegister() throws Exception {
//given
String title = "title";
String content = "content";
PostsSaveRequestDto requestDto = PostsSaveRequestDto.builder()
.title(title)
.content(content)
.author("author")
.build();
String url = "http://localhost:" + port + "/api/v1/posts";
//when
mvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(new ObjectMapper().writeValueAsString(requestDto)))
.andExpect(status().isOk());
//then
List<Posts> all = postsRepository.findAll();
assertThat(all.get(0).getTitle()).isEqualTo(title);
assertThat(all.get(0).getContent()).isEqualTo(content);
}
- @WithMockUser(roles = "USER")
- 인증된 가짜 사용자를 만들어 사용
- rolse에 권한 추가 가능 (ROLE_USER 권한 가진 사용자가 API 요청하는 것과 동일한 효과)
- MockMvc에서만 작동함
@SpringBootTest에서 MockMvc 사용하는 방법
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before //테스트 시작 전에 MockMvc 인스턴스를 생성함
public void setup(){
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
}
- @Before
- 테스트 시작 전에 MockMvc 인스턴스 생성
- mvc.perform (위의 소스코드에 있음)
- 생성된 MockMvc를 통해 API 테스트함
- 바디 영역은 문자열 표현 위해 ObjectMapper로 문자열 JSON으로 변환
3. @WebMvcTest에서 CustomOAuth2UserService 찾을 수 없음
HelloControllerTest는 @WebMvcTest를 사용하는데 이 @는 CustomOAuth2UserService를 스캔하지 않음
- @WebMvcTest
- WebSecurityConfigurerAdapter, WebMvcConfigurer를 비롯한 @ControllerAdvice, @Controller를 읽음
- @Repository, @Service, @Component는 스캔 대상이 아님
- -> SecurityConfig 생성 위한 CustomOAuth2UserService 못 읽음
해결 방법
- 스캔 대상에서 SecurityConfig 제거하기
- @WithMockUser를 사용해 가짜 사용자 생성
- -> At least one JPA metamodel must be present! 에러 발생함
에러 이유
@EnableJpaAuditing을 사용하기 위해서 최소 하나의 엔티티 클래스가 필요함
@WebMvcTest라서 엔티티 클래스가 없음
해결 방법
- @SpringBootApplication과 @EnableJpaAuditing이 같이 있어서 항상 스캔함
- -> 둘을 분리
- Application.java에서 @EnableJpaAuditing 제거
JpaConfig 생성
package com.springAWS.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
@Configuration
@EnableJpaAuditing //JPA Auditing 활성화
public class JpaConfig {
}