Table of Contents
Spring Boot Test
JUnit 4.x 기준으로 작성합니다.
개발환경
- Spring Boot 2.1.x
- Gradle 4.10.2
- junit 4.12
build.gradle 수정
build.gradle
......
dependencies {
// ......
testCompile("org.springframework.security:spring-security-test")
// ......
}
......
테스트용 application.properties 생성
src/test/resources/application.properties
# 빈(empty) 파일로 생성합니다.
# 파일이 비어있으면 스프링은 자동으로 h2 를 데이타베이스로 설정합니다.
파일을 생성하지 않고 @AutoConfigureTestDatabase
를 이용해 원래의 DB 를 사용할 수 있습니다.
given-when-then
테스트 방법은 given-when-then
기법을 사용합니다.
given
파트에서는 테스트를 위한 기초환경을 구성합니다.
when
에서 테스트코드를 작성하고, then
에서 테스트결과를 검증합니다.
도메인 레이어 테스트하기
src/test/java/kr/co/episode/example/domain/posts/PostsRepositoryTest.java
@RunWith(SpringRunner.class)
@DataJpaTest
// @AutoConfigureTestDatabase(replace= AutoConfigureTestDatabase.Replace.NONE)
public class PostsRepositoryTest {
@Autowired
private PostsRepository postsRepository;
@Test
public void save() {
// given
Posts posts = Posts.builder()
.title("title")
.author("author")
.content("content")
.build();
// when
Long id = postsRepository.save(posts).getId();
// then
Optional<Posts> saved = postsRepository.findById(id);
assertTrue(saved.isPresent());
assertEquals(saved.get().getTitle(), "title");
assertEquals(saved.get().getAuthor(), "author");
assertEquals(saved.get().getContent(), "content");
}
@Test
public void update() {
// given
Long id = saveOnePost();
Optional<Posts> saved = postsRepository.findById(id);
// when
assertTrue(saved.isPresent());
saved.get().update("title2", "content2");
Optional<Posts> updated = postsRepository.findById(id);
// then
assertTrue(updated.isPresent());
assertEquals(updated.get().getTitle(), "title2");
assertEquals(updated.get().getContent(), "content2");
}
@Test
public void findById() {
// given
Long id = saveOnePost();
// when
Optional<Posts> saved = postsRepository.findById(id);
// then
assertTrue(saved.isPresent());
assertEquals(saved.get().getTitle(), "title");
assertEquals(saved.get().getAuthor(), "author");
assertEquals(saved.get().getContent(), "content");
}
@Test
public void delete() {
// given
Long id = saveOnePost();
// when
postsRepository.deleteById(id);
// then
Optional<Posts> deleted = postsRepository.findById(id);
assertTrue(deleted.isEmpty());
}
@Test
public void findAllDesc() {
// given
Long id = saveOnePost();
// when
List<Posts> postsList = postsRepository.findAllDesc();
// then
assertEquals(postsList.size(), 1);
}
private Long saveOnePost() {
Posts posts = Posts.builder()
.title("title")
.author("author")
.content("content")
.build();
return postsRepository.save(posts).getId();
}
}
src/test/java/kr/co/episode/example/domain/posts/PostsPagingRepositoryTest.java
@RunWith(SpringRunner.class)
@DataJpaTest
public class PostsPagingRepositoryTest {
@Autowired
private PostsRepository postsRepository;
@Autowired
private PostsPagingRepository postsPagingRepository;
@Test
public void search() {
// given
PostsSearchDto postsSearchDto = PostsSearchDto.builder()
.title("title")
.author("author")
.orderBy(false)
.build();
Pageable pageable = PageRequest.of(0, 10);
ArrayList<Posts> postsArrayList = new ArrayList<>();
for (int i = 0; i < 10; i++) {
Posts post = Posts.builder()
.title("title" + 1)
.author("author")
.content("content")
.build();
postsRepository.save(post);
postsArrayList.add(post);
}
// when
Page<Posts> posts = postsPagingRepository.search(pageable, postsSearchDto.toEntity());
// then
for (int i = 0; i < 1; i++) {
String a = posts.getContent().get(i).getTitle();
String b = postsArrayList.get(i).getTitle();
assertEquals(a, b);
}
}
}
컨트롤러 테스트하기
테스트용 application.properties 수정
실제로 접속하지는 않으므로 client-id/client-secret 은 아무 값을 입력해도 됩니다.
src/test/resources/application.properties
spring.security.oauth2.client.registration.google.client-id=aaaa
spring.security.oauth2.client.registration.google.client-secret=bbbb
spring.security.oauth2.client.registration.google.scope=profile,email
API 컨트롤러 테스트하기
실제로 RestController 를 랜덤포트로 실행하고, @WithMockUser(roles="USER")
를 이용해 권한을 부여합니다.
src/test/java/kr/co/episode/example/web/PostsApiControllerTest.java
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class PostsApiControllerTest {
@LocalServerPort
private int port;
@Autowired
private PostsRepository postsRepository;
@Autowired
private WebApplicationContext context;
private MockMvc mvc;
@Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.apply(springSecurity())
.build();
}
@After
public void tearDown() throws Exception {
postsRepository.deleteAll();
}
@Test
@WithMockUser(roles="USER")
public void save() throws Exception {
// given
String title = "title";
String content = "content";
String author = "author";
PostsSaveRequestDto requestDto = PostsSaveRequestDto.builder()
.title(title)
.content(content)
.author(author)
.build();
String url = "http://localhost:" + port + "/api/v1/posts";
// when
// org.springframework.test.web.servlet 을 임포트합니다.
mvc.perform(post(url)
.contentType(MediaType.APPLICATION_JSON_UTF8)
.content(new ObjectMapper().writeValueAsString(requestDto)))
.andExpect(status().isOk());
// then
List<Posts> all = postsRepository.findAll();
// org.assertj.core.api.Assertions 을 임포트합니다.
assertThat(all.get(0).getTitle()).isEqualTo(title);
assertThat(all.get(0).getContent()).isEqualTo(content);
}
@Test
@WithMockUser(roles="USER")
public void update() throws Exception {
// given
Posts savedPosts = postsRepository.save(Posts.builder()
.title("title")
.content("content")
.author("author")
.build());
Long updateId = savedPosts.getId();
String expectedTitle = "title2";
String expectedContent = "content2";
PostsUpdateRequestDto requestDto = PostsUpdateRequestDto.builder()
.title(expectedTitle)
.content(expectedContent)
.build();
String url = "http://localhost:" + port + "/api/v1/posts/" + updateId;
// when
mvc.perform(put(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(expectedTitle);
assertThat(all.get(0).getContent()).isEqualTo(expectedContent);
}
}
컨트롤러 테스트하기
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = RANDOM_PORT)
public class IndexControllerTest {
@Autowired
private PostsRepository postsRepository;
@Autowired
private TestRestTemplate restTemplate;
@Before
public void setUp() throws Exception {
postsRepository.save(Posts.builder()
.title("title title title")
.content("content content content")
.author("author author author")
.build());
}
@After
public void tearDown() throws Exception {
postsRepository.deleteAll();
}
@Test
public void index() {
// given
// when
String body = this.restTemplate.getForObject("/", String.class);
// then
// org.assertj.core.api.Assertions 을 임포트합니다.
// org.junit.Assert 가 임포트되어 있으면 제거합니다.
assertThat(body).contains("title title title");
}
}