์ ๋ฒ ํฌ์คํ ์ ์ด์ด์ ์ด๋ฒ์๋ QueryDSL์ ์ฌ์ฉํด์ ๊ฒ์ํ ๊ฒ์(์กฐ๊ฑด์ ๋ฐ๋ฅธ ๋์ ๊ฒ์), ํ์ด์ง ๊ธฐ๋ฅ์ ๊ตฌํํ์ฌ ๊ธฐ๋ณธ์ ์ธ ๊ฒ์ํ์ ์์ฑ์์ผ ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค!
- ์ํ๋ฆฌํฐ๋ฅผ ์ด์ฉํ JSON ๋ฐ์ดํฐ๋ก ๋ก๊ทธ์ธ (์๋ฃ)
- JWT๋ฅผ ์ด์ฉํ ์ธ์ฆ (์๋ฃ)
- ๋๋ฉ์ธ, ํ ์ด๋ธ ์ค๊ณ, ์ํฐํฐ ์์ฑ (์๋ฃ)
- ๋๊ธ ์ญ์ ๋ก์ง ๊ตฌํ (์๋ฃ)
- ํ์๊ฐ์ + ์ ๋ณด์์ ๋ฑ ํ์ ์๋น์ค ๊ตฌํ (์๋ฃ)
- ๊ฒ์ํ ์๋น์ค ๊ตฌํ (์งํ ์ค)
- ๋๊ธ ์๋น์ค ๊ตฌํ (1๋๊ธ -> *(๋ฌดํ) ๋๋๊ธ ๊ตฌ์กฐ) (์๋ฃ)
- ์์ธ ์ฒ๋ฆฌ (์๋ฃ)
- ์์ธ ๋ฉ์ธ์ง ๊ตญ์ ํ
- ์นดํ ๊ณ ๋ฆฌ๋ณ ๊ฒ์ํ ๋ถ๋ฅ
- ๊ฒ์๊ธ ํ์ด์ง (์งํ ์ค)
- ๋์ ์ธ ๊ฒ์ ์กฐ๊ฑด์ ์ฌ์ฉํ ๊ฒ์ (์งํ ์ค)
- ์ฌ์ฉ์ ๊ฐ ์ชฝ์ง ๊ธฐ๋ฅ
- ๋ฌดํ ์ชฝ์ง ์คํฌ๋กค
- ๊ฒ์๋ฌผ & ๋๊ธ์ ๋ํ ์๋
- ์ชฝ์ง์ ๋ํ ์๋
- ์ ์ํ ์ฌ์ฉ์ ๊ฐ ์ค์๊ฐ ์ฑํ
- ํ์๊ฐ์ ์ ๊ฒ์ฆ(์: XX๋ํ๊ต XX๊ณผ๊ฐ ์๋๋ฉด ๊ฐ์ ํ ์ ์๊ฒ)
- Swagger๋ฅผ ์ฌ์ฉํ API ๋ฌธ์ ๋ง๋ค๊ธฐ
- ์ ๊ณ & ๋ธ๋๋ฆฌ์คํธ ๊ธฐ๋ฅ
- AOP๋ฅผ ํตํ ๋ก๊ทธ
- ์ด๋๋ฏผ ํ์ด์ง
- ์บ์
- ๋ฐฐํฌ (+ ๋ฌด์ค๋จ ๋ฐฐํฌ)
- ๋ฐฐํฌ ์๋ํ
- ํฌํธ์ ์ด๋ํฐ ์ค๊ณ๋ฅผ ๋ฐ๋ฅด๋ ํจํค์ง ๊ตฌ์กฐ ์ค๊ณํ๊ธฐ
- ...
์ปค์คํ JPA Repository ๋ง๋ค๊ธฐ
๋จผ์ QueryDSL์ ์ฌ์ฉํ ๊ฒ์ด๊ธฐ ๋๋ฌธ์, ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ํ๋ ๋ง๋ค์ด์ฃผ๋๋ก ํ๊ฒ ์ต๋๋ค.
์์น๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
CustomPostRepository ์์ฑ
public interface CustomPostRepository {
Page<Post> search(PostSearchCondition postSearchCondition, Pageable pageable);
}
์ฝ๋๋ ์์ ๊ฐ์ต๋๋ค.
Page<Post>๋ฅผ ๋ฐํ ๊ฐ์ฒด๋ก ์ค์ ํ์ฌ, Page์ ๊ด๋ จ๋ ์ ๋ณด๋ค์ ์ฝ๊ฒ ์ป์ด์ฌ ์ ์๋๋ก ํด์ฃผ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ํด๋น CustomPostRepository๋ฅผ PostRepository ํ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ ์ํด ๋ค์์ ์ถ๊ฐํด์ค๋๋ค.
public interface PostRepository extends JpaRepository<Post, Long> , CustomPostRepository{
@EntityGraph(attributePaths = {"writer"})
Optional<Post> findWithWriterById(Long id);
}
๋ณด์๋ฉด extends์ CustomPostRepository๊ฐ ์ถ๊ฐ๋์์ต๋๋ค.
์ด๋ ๊ฒ๋ง ํด์ฃผ๋ฉด ์ง์ ์ ์ํ Repository๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ๋ฉ๋๋ค.
PostSearchCondition ๊ตฌํ
@Data
public class PostSearchCondition {
private String title;
private String content;
}
์ ๋ชฉ๊ณผ ๋ด์ฉ์ผ๋ก ๊ฒ์ํ ์ ์๋๋ก ํ๊ฒ ์ต๋๋ค.
CustomPostRepositoryImpl ๊ตฌํ
import static boardexample.myboard.domain.member.QMember.member;
import static boardexample.myboard.domain.post.QPost.post;
@Repository
public class CustomPostRepositoryImpl implements CustomPostRepository {
private final JPAQueryFactory query;
public CustomPostRepositoryImpl(EntityManager em) {
query = new JPAQueryFactory(em);
}
@Override
public Page<Post> search(PostSearchCondition postSearchCondition, Pageable pageable) {
List<Post> content = query.selectFrom(post)
.where(
contentHasStr(postSearchCondition.getContent()),
titleHasStr(postSearchCondition.getTitle())
)
.leftJoin(post.writer, member)
.fetchJoin()
.orderBy(post.createdDate.desc())//์ต์ ๋ ์ง๋ถํฐ
.offset(pageable.getOffset())
.limit(pageable.getPageSize())
.fetch(); //Count ์ฟผ๋ฆฌ ๋ฐ์ X
JPAQuery<Post> countQuery = query.selectFrom(post)
.where(
contentHasStr(postSearchCondition.getContent()),
titleHasStr(postSearchCondition.getTitle())
);
return PageableExecutionUtils.getPage(content, pageable, () -> countQuery.fetch().size());
}
private BooleanExpression contentHasStr(String content) {
return StringUtils.hasLength(content) ? post.content.contains(content) : null;
}
private BooleanExpression titleHasStr(String title) {
return StringUtils.hasLength(title) ? post.title.contains(title) : null;
}
}
querydsl์ ์ฌ์ฉํ์ฌ ๊ตฌํํ์์ต๋๋ค.
์ค๊ฐ์ ์์ฑ์(writer)์ ๋ํด์ fetch join์ ์ ์ฉํ์ฌ ์ฟผ๋ฆฌ๋ฅผ ์ต์ ํ ํ์์ต๋๋ค.
์ ์ฝ๋๋ฅผ ์ ๋ชจ๋ฅด๊ฒ ๋ค๋ฉด ๋ค์์ ์ฐธ๊ณ ํด์ฃผ์ธ์
('Where ์ ์ ๋ค์ค ํ๋ผ๋ฏธํฐ ์ฌ์ฉ' ๋ถ๋ถ์ ๋๋ค)
์ด์ DB์์ ๊ฒ์ํ๋ ์ฝ๋๋ ์์ฑ์ ์๋ฃํ์ต๋๋ค. ์ด์ ์กฐํ๋ ๊ฒฐ๊ณผ๋ฅผ ์ ์ ํ DTO๋ก ๋ฐํํ์ฌ ๋๊ฒจ์ฃผ๋๋ก DTO๋ฅผ ๊ตฌํํ๊ฒ ์ต๋๋ค.
PostPagingDto ๊ตฌํ
@Data
@NoArgsConstructor
public class PostPagingDto {
private int totalPageCount;//์ด ๋ชํ์ด์ง๊ฐ ์กด์ฌํ๋์ง
private int currentPageNum;//ํ์ฌ ๋ช ํ์ด์ง์ธ์ง
private long totalElementCount; //์กด์ฌํ๋ ๊ฒ์๊ธ์ ์ด ๊ฐ์
private int currentPageElementCount; //ํ์ฌ ํ์ด์ง์ ์กด์ฌํ๋ ๊ฒ์๊ธ ์
private List<BriefPostInfo> simpleLectureDtoList = new ArrayList<>();
public PostPagingDto(Page<Post> searchResults) {
this.totalPageCount = searchResults.getTotalPages();
this.currentPageNum = searchResults.getNumber();
this.totalElementCount = searchResults.getTotalElements();
this.currentPageElementCount = searchResults.getNumberOfElements();
this.simpleLectureDtoList = searchResults.getContent().stream().map(BriefPostInfo::new).toList();
}
}
BriefPostInfo๋ ํด์ ๊ทธ๋๋ก ๊ฐ๋จํ Post์ ์ ๋ณด๋ผ๋ ๋ป์ผ๋ก, ํฌ์คํธ์ ๋ํด์ ๊ฐ๋จํ ์ ๋ณด๋ง ๊ฐ์ง๊ณ ์์ต๋๋ค.
(๋ฆฌ์คํธ๋ก ์กฐํ ์ ์ธ์ธํ ๋ถ๋ถ์(๋๊ธ์ ๋ด์ฉ ๋ฑ) ํ์์๊ธฐ ๋๋ฌธ์ ๋๋ค.)
BriefPostInfo ์์ฑ
@Data
@NoArgsConstructor
public class BriefPostInfo {
private Long postId;
private String title;//์ ๋ชฉ
private String content;//๋ด์ฉ
private String writerName;//์์ฑ์์ ์ด๋ฆ
private String createdDate; //์์ฑ์ผ
public BriefPostInfo(Post post) {
this.postId = post.getId();
this.title = post.getTitle();
this.content = post.getContent();
this.writerName = post.getWriter().getName();
this.createdDate = post.getCreatedDate().toString();
}
}
์ ๋ชฉ๊ณผ ๋ด์ฉ, ์์ฑ์์ ์ด๋ฆ๊ณผ ์์ฑ์ผ๋ง ๊ฐ์ง๊ณ ์์ต๋๋ค.
PostServiceImpl์ ์ถ๊ฐ
@Override
public PostPagingDto getPostList(Pageable pageable, PostSearchCondition postSearchCondition) {
return new PostPagingDto(postRepository.search(postSearchCondition, pageable));
}
Service์ ์ฝ๋๋ ๊ฐ๋จํฉ๋๋ค. ๊ทธ๋ฅ ์กฐํํ ๊ฒฐ๊ณผ๋ฅผ ์์ฑ์์ ์ธ์๋ก๋ง ๋ฃ์ด์ฃผ์๋ฉด ๋ฉ๋๋ค.
์ด์ ํ ์คํธ์ฝ๋๋ฅผ ์์ฑํด๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๊ฒ์๊ธ ๊ฒ์ ํ ์คํธ์ฝ๋ ์์ฑ
@Test
public void ํฌ์คํธ_๊ฒ์_์กฐ๊ฑด์์() throws Exception {
//given
/**
* MEMBER ์ ์ฅ
*/
Member member1 = memberRepository.save(Member.builder().username("username1").password("1234567890").name("USER1").nickName("๋ฐฅ ์๋จน๋ ๋ํ์ด1").role(Role.USER).age(22).build());
/**
* Post ์์ฑ
*/
final int POST_COUNT = 50;
for(int i = 1; i<= POST_COUNT; i++ ){
Post post = Post.builder().title("๊ฒ์๊ธ"+ i).content("๋ด์ฉ"+i).build();
post.confirmWriter(member1);
postRepository.save(post);
}
clear();
//when
final int PAGE = 0;
final int SIZE = 20;
PageRequest pageRequest = PageRequest.of(PAGE, SIZE);
PostSearchCondition postSearchCondition = new PostSearchCondition();
PostPagingDto postList = postService.getPostList(pageRequest, postSearchCondition);
//then
assertThat(postList.getTotalElementCount()).isEqualTo(POST_COUNT);
assertThat(postList.getTotalPageCount()).isEqualTo((POST_COUNT % SIZE == 0)
? POST_COUNT/SIZE
: POST_COUNT/SIZE + 1);
assertThat(postList.getCurrentPageNum()).isEqualTo(PAGE);
assertThat(postList.getCurrentPageElementCount()).isEqualTo(SIZE);
}
@Test
public void ํฌ์คํธ_๊ฒ์_์ ๋ชฉ์ผ์น() throws Exception {
//given
/**
* MEMBER ์ ์ฅ
*/
Member member1 = memberRepository.save(Member.builder().username("username1").password("1234567890").name("USER1").nickName("๋ฐฅ ์๋จน๋ ๋ํ์ด1").role(Role.USER).age(22).build());
/**
* ์ผ๋ฐ POST ์์ฑ
*/
final int DEFAULT_POST_COUNT = 100;
for(int i = 1; i<=DEFAULT_POST_COUNT; i++ ){
Post post = Post.builder().title("๊ฒ์๊ธ"+ i).content("๋ด์ฉ"+i).build();
post.confirmWriter(member1);
postRepository.save(post);
}
/**
* ์ ๋ชฉ์ AAA๊ฐ ๋ค์ด๊ฐ POST ์์ฑ
*/
final String SEARCH_TITLE_STR = "AAA";
final int COND_POST_COUNT = 100;
for(int i = 1; i<=COND_POST_COUNT; i++ ){
Post post = Post.builder().title(SEARCH_TITLE_STR+ i).content("๋ด์ฉ"+i).build();
post.confirmWriter(member1);
postRepository.save(post);
}
clear();
//when
final int PAGE = 2;
final int SIZE = 20;
PageRequest pageRequest = PageRequest.of(PAGE, SIZE);
PostSearchCondition postSearchCondition = new PostSearchCondition();
postSearchCondition.setTitle(SEARCH_TITLE_STR);
PostPagingDto postList = postService.getPostList(pageRequest, postSearchCondition);
//then
assertThat(postList.getTotalElementCount()).isEqualTo(COND_POST_COUNT);
assertThat(postList.getTotalPageCount()).isEqualTo((COND_POST_COUNT % SIZE == 0)
? COND_POST_COUNT/SIZE
: COND_POST_COUNT/SIZE + 1);
assertThat(postList.getCurrentPageNum()).isEqualTo(PAGE);
assertThat(postList.getCurrentPageElementCount()).isEqualTo(SIZE);
}
@Test
public void ํฌ์คํธ_๊ฒ์_๋ด์ฉ์ผ์น() throws Exception {
//given
/**
* MEMBER ์ ์ฅ
*/
Member member1 = memberRepository.save(Member.builder().username("username1").password("1234567890").name("USER1").nickName("๋ฐฅ ์๋จน๋ ๋ํ์ด1").role(Role.USER).age(22).build());
/**
* ์ผ๋ฐ POST ์์ฑ
*/
final int DEFAULT_POST_COUNT = 100;
for(int i = 1; i<=DEFAULT_POST_COUNT; i++ ){
Post post = Post.builder().title("๊ฒ์๊ธ"+ i).content("๋ด์ฉ"+i).build();
post.confirmWriter(member1);
postRepository.save(post);
}
/**
* ์ ๋ชฉ์ AAA๊ฐ ๋ค์ด๊ฐ POST ์์ฑ
*/
final String SEARCH_CONTENT_STR = "AAA";
final int COND_POST_COUNT = 100;
for(int i = 1; i<=COND_POST_COUNT; i++ ){
Post post = Post.builder().title("๊ฒ์๊ธ"+ i).content(SEARCH_CONTENT_STR+i).build();
post.confirmWriter(member1);
postRepository.save(post);
}
clear();
//when
final int PAGE = 2;
final int SIZE = 20;
PageRequest pageRequest = PageRequest.of(PAGE, SIZE);
PostSearchCondition postSearchCondition = new PostSearchCondition();
postSearchCondition.setContent(SEARCH_CONTENT_STR);
PostPagingDto postList = postService.getPostList(pageRequest, postSearchCondition);
//then
assertThat(postList.getTotalElementCount()).isEqualTo(COND_POST_COUNT);
assertThat(postList.getTotalPageCount()).isEqualTo((COND_POST_COUNT % SIZE == 0)
? COND_POST_COUNT/SIZE
: COND_POST_COUNT/SIZE + 1);
assertThat(postList.getCurrentPageNum()).isEqualTo(PAGE);
assertThat(postList.getCurrentPageElementCount()).isEqualTo(SIZE);
}
@Test
public void ํฌ์คํธ_๊ฒ์_์ ๋ชฉ๊ณผ๋ด์ฉ์ผ์น() throws Exception {
//given
/**
* MEMBER ์ ์ฅ
*/
Member member1 = memberRepository.save(Member.builder().username("username1").password("1234567890").name("USER1").nickName("๋ฐฅ ์๋จน๋ ๋ํ์ด1").role(Role.USER).age(22).build());
/**
* ์ผ๋ฐ POST ์์ฑ
*/
final int DEFAULT_POST_COUNT = 100;
for(int i = 1; i<=DEFAULT_POST_COUNT; i++ ){
Post post = Post.builder().title("๊ฒ์๊ธ"+ i).content("๋ด์ฉ"+i).build();
post.confirmWriter(member1);
postRepository.save(post);
}
/**
* ์ ๋ชฉ์ AAA๊ฐ ๋ค์ด๊ฐ POST ์์ฑ
*/
final String SEARCH_TITLE_STR = "AAA";
final String SEARCH_CONTENT_STR = "BBB";
final int COND_POST_COUNT = 100;
for(int i = 1; i<=COND_POST_COUNT; i++ ){
Post post = Post.builder().title(SEARCH_TITLE_STR+ i).content(SEARCH_CONTENT_STR+i).build();
post.confirmWriter(member1);
postRepository.save(post);
}
clear();
//when
final int PAGE = 2;
final int SIZE = 20;
PageRequest pageRequest = PageRequest.of(PAGE, SIZE);
PostSearchCondition postSearchCondition = new PostSearchCondition();
postSearchCondition.setTitle(SEARCH_TITLE_STR);
postSearchCondition.setContent(SEARCH_CONTENT_STR);
PostPagingDto postList = postService.getPostList(pageRequest, postSearchCondition);
//then
assertThat(postList.getTotalElementCount()).isEqualTo(COND_POST_COUNT);
assertThat(postList.getTotalPageCount()).isEqualTo((COND_POST_COUNT % SIZE == 0)
? COND_POST_COUNT/SIZE
: COND_POST_COUNT/SIZE + 1);
assertThat(postList.getCurrentPageNum()).isEqualTo(PAGE);
assertThat(postList.getCurrentPageElementCount()).isEqualTo(SIZE);
}
PostController ์์ฑ
์ด์ ํด๋น ์๋น์ค๋ฅผ ๊ฐ์ง๊ณ Controller๋ฅผ ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
@RestController
@RequiredArgsConstructor
public class PostController {
private final PostService postService;
/**
* ๊ฒ์๊ธ ์ ์ฅ
*/
@ResponseStatus(HttpStatus.CREATED)
@PostMapping("/post")
public void save(@Valid @ModelAttribute PostSaveDto postSaveDto){
postService.save(postSaveDto);
}
/**
* ๊ฒ์๊ธ ์์
*/
@ResponseStatus(HttpStatus.OK)
@PutMapping("/post/{postId}")
public void update(@PathVariable("postId") Long postId,
@ModelAttribute PostUpdateDto postUpdateDto){
postService.update(postId, postUpdateDto);
}
/**
* ๊ฒ์๊ธ ์ญ์
*/
@ResponseStatus(HttpStatus.OK)
@DeleteMapping("/post/{postId}")
public void delete(@PathVariable("postId") Long postId){
postService.delete(postId);
}
/**
* ๊ฒ์๊ธ ์กฐํ
*/
@GetMapping("/post/{postId}")
public ResponseEntity getInfo(@PathVariable("postId") Long postId){
return ResponseEntity.ok(postService.getPostInfo(postId));
}
/**
* ๊ฒ์๊ธ ๊ฒ์
*/
@GetMapping("/post")
public ResponseEntity search(Pageable pageable,
@ModelAttribute PostSearchCondition postSearchCondition){
return ResponseEntity.ok(postService.getPostList(pageable,postSearchCondition));
}
}
์ด์ ํด๋น ์ปจํธ๋กค๋ฌ์ ๋ํ ํ ์คํธ์ฝ๋๋ฅผ ์์ฑํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
ํ ์คํธ์ฝ๋ ์์ฑ
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringBootTest
@AutoConfigureMockMvc
@Transactional
class PostControllerTest {
@Autowired MockMvc mockMvc;
@Autowired EntityManager em;
@Autowired MemberRepository memberRepository;
@Autowired PostRepository postRepository;
ObjectMapper objectMapper = new ObjectMapper();
@Autowired PasswordEncoder passwordEncoder;
@Autowired
JwtService jwtService;
final String USERNAME = "username1";
private static Member member;
private void clear() {
em.flush();
em.clear();
}
@BeforeEach
public void signUpMember(){
member = memberRepository.save(Member.builder().username(USERNAME).password("1234567890").name("USER1").nickName("๋ฐฅ ์๋จน๋ ๋ํ์ด1").role(Role.USER).age(22).build());
clear();
}
private String getAccessToken(){
return jwtService.createAccessToken(USERNAME);
}
private MockMultipartFile getMockUploadFile() throws IOException {
//TODO : name์ด ์ค์
return new MockMultipartFile("uploadFile", "file.jpg", "image/jpg", new FileInputStream("C:/Users/user/Desktop/tistory/diary.jpg"));
}
/**
* ๊ฒ์๊ธ ์ ์ฅ
*/
@Test
public void ๊ฒ์๊ธ_์ ์ฅ_์ฑ๊ณต() throws Exception {
//given
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("title", "์ ๋ชฉ");
map.add("content", "๋ด์ฉ");
//when
mockMvc.perform(
post("/post")
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA).params(map))
.andExpect(status().isCreated());
//then
Assertions.assertThat(postRepository.findAll().size()).isEqualTo(1);
}
/**
* ๊ฒ์๊ธ ์ ์ฅ
*/
@Test
public void ๊ฒ์๊ธ_์ ์ฅ_์คํจ_์ ๋ชฉ์ด๋_๋ด์ฉ์ด_์์() throws Exception {
//given
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add("title", "์ ๋ชฉ");
//when, then
mockMvc.perform(
post("/post")
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
.params(map))
.andExpect(status().isBadRequest());
map = new LinkedMultiValueMap<>();
map.add("content", "๋ด์ฉ");
mockMvc.perform(
post("/post")
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
.params(map))
.andExpect(status().isBadRequest());
}
/**
* ๊ฒ์๊ธ ์์
*/
@Test
public void ๊ฒ์๊ธ_์์ _์ ๋ชฉ๋ณ๊ฒฝ_์ฑ๊ณต() throws Exception {
//given
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(member);
Post savePost = postRepository.save(post);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
final String UPDATE_TITLE = "์ ๋ชฉ";
map.add("title", UPDATE_TITLE);
//when
mockMvc.perform(
put("/post/"+savePost.getId())
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
.params(map))
.andExpect(status().isOk());
//then
Assertions.assertThat(postRepository.findAll().get(0).getTitle()).isEqualTo(UPDATE_TITLE);
}
/**
* ๊ฒ์๊ธ ์์
*/
@Test
public void ๊ฒ์๊ธ_์์ _๋ด์ฉ๋ณ๊ฒฝ_์ฑ๊ณต() throws Exception {
//given
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(member);
Post savePost = postRepository.save(post);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
final String UPDATE_CONTENT = "๋ด์ฉ";
map.add("content", UPDATE_CONTENT);
//when
mockMvc.perform(
put("/post/"+savePost.getId())
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
.params(map))
.andExpect(status().isOk());
//then
Assertions.assertThat(postRepository.findAll().get(0).getContent()).isEqualTo(UPDATE_CONTENT);
}
/**
* ๊ฒ์๊ธ ์์
*/
@Test
public void ๊ฒ์๊ธ_์์ _์ ๋ชฉ๋ด์ฉ๋ณ๊ฒฝ_์ฑ๊ณต() throws Exception {
//given
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(member);
Post savePost = postRepository.save(post);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
final String UPDATE_CONTENT = "๋ด์ฉ";
final String UPDATE_TITlE = "์ ๋ชฉ";
map.add("title", UPDATE_TITlE);
map.add("content", UPDATE_CONTENT);
//when
mockMvc.perform(
put("/post/"+savePost.getId())
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
.params(map))
.andExpect(status().isOk());
//then
Assertions.assertThat(postRepository.findAll().get(0).getContent()).isEqualTo(UPDATE_CONTENT);
Assertions.assertThat(postRepository.findAll().get(0).getTitle()).isEqualTo(UPDATE_TITlE);
}
/**
๊ฒ์๊ธ ์์
*/
@Test
public void ๊ฒ์๊ธ_์์ _์
๋ก๋ํ์ผ์ถ๊ฐ_์ฑ๊ณต() throws Exception {
//given
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(member);
Post savePost = postRepository.save(post);
MockMultipartFile mockUploadFile = getMockUploadFile();
//when
MockMultipartHttpServletRequestBuilder requestBuilder = multipart("/post/" + savePost.getId());
requestBuilder.with(request -> {
request.setMethod(HttpMethod.PUT.name());
return request;
});
mockMvc.perform(requestBuilder
.file(getMockUploadFile())
.contentType(MediaType.MULTIPART_FORM_DATA)
.header("Authorization", "Bearer " + getAccessToken()))
.andExpect(status().isOk());
/*mockMvc.perform(multipart("/post/"+savePost.getId())
.file(getMockUploadFile())
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
)
.andExpect(status().isOk());
*/
//then
String filePath = postRepository.findAll().get(0).getFilePath();
Assertions.assertThat(filePath).isNotNull();
Assertions.assertThat(new File(filePath).delete()).isTrue();
}
/**
๊ฒ์๊ธ ์์
*/
@Autowired private FileService fileService;
@Test
public void ๊ฒ์๊ธ_์์ _์
๋ก๋ํ์ผ์ ๊ฑฐ_์ฑ๊ณต() throws Exception {
//given
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(member);
String path = fileService.save(getMockUploadFile());
post.updateFilePath(path);
Post savePost = postRepository.save(post);
Assertions.assertThat(postRepository.findAll().get(0).getFilePath()).isNotNull();
MockMultipartFile mockUploadFile = getMockUploadFile();
//when
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
final String UPDATE_CONTENT = "๋ด์ฉ";
final String UPDATE_TITlE = "์ ๋ชฉ";
map.add("title", UPDATE_TITlE);
map.add("content", UPDATE_CONTENT);
//when
mockMvc.perform(
put("/post/"+savePost.getId())
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
.params(map))
.andExpect(status().isOk());
//then
Assertions.assertThat(postRepository.findAll().get(0).getContent()).isEqualTo(UPDATE_CONTENT);
Assertions.assertThat(postRepository.findAll().get(0).getTitle()).isEqualTo(UPDATE_TITlE);
Assertions.assertThat(postRepository.findAll().get(0).getFilePath()).isNull();
}
/**
* ๊ฒ์๊ธ ์์
*/
@Test
public void ๊ฒ์๊ธ_์์ _์คํจ_๊ถํ์์() throws Exception {
//given
Member newMember = memberRepository.save(Member.builder().username("newMEmber1123").password("!23123124421").name("123213").nickName("123").age(22).role(Role.USER).build());
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(newMember);
Post savePost = postRepository.save(post);
MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
final String UPDATE_CONTENT = "๋ด์ฉ";
final String UPDATE_TITlE = "์ ๋ชฉ";
map.add("title", UPDATE_TITlE);
map.add("content", UPDATE_CONTENT);
//when
mockMvc.perform(
put("/post/"+savePost.getId())
.header("Authorization", "Bearer "+ getAccessToken())
.contentType(MediaType.MULTIPART_FORM_DATA)
.params(map))
.andExpect(status().isForbidden());
//then
Assertions.assertThat(postRepository.findAll().get(0).getContent()).isEqualTo("์์ ์ ๋ด์ฉ");
Assertions.assertThat(postRepository.findAll().get(0).getTitle()).isEqualTo("์์ ์ ์ ๋ชฉ");
}
/**
* ๊ฒ์๊ธ ์ญ์
*/
@Test
public void ๊ฒ์๊ธ_์ญ์ _์ฑ๊ณต() throws Exception {
//given
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(member);
Post savePost = postRepository.save(post);
//when
mockMvc.perform(
delete("/post/"+savePost.getId())
.header("Authorization", "Bearer "+ getAccessToken())
).andExpect(status().isOk());
//then
Assertions.assertThat(postRepository.findAll().size()).isEqualTo(0);
}
/**
* ๊ฒ์๊ธ ์ญ์
*/
@Test
public void ๊ฒ์๊ธ_์ญ์ _์คํจ_๊ถํ์์() throws Exception {
//given
Member newMember = memberRepository.save(Member.builder().username("newMEmber1123").password("!23123124421").name("123213").nickName("123").age(22).role(Role.USER).build());
Post post = Post.builder().title("์์ ์ ์ ๋ชฉ").content("์์ ์ ๋ด์ฉ").build();
post.confirmWriter(newMember);
Post savePost = postRepository.save(post);
//when
mockMvc.perform(
delete("/post/"+savePost.getId())
.header("Authorization", "Bearer "+ getAccessToken())
).andExpect(status().isForbidden());
//then
Assertions.assertThat(postRepository.findAll().size()).isEqualTo(1);
}
/**
* ๊ฒ์๊ธ ์กฐํ
*/
@Test
public void ๊ฒ์๊ธ_์กฐํ() throws Exception {
//given
Member newMember = memberRepository.save(Member.builder().username("newMEmber1123").password("!23123124421").name("123213").nickName("123").age(22).role(Role.USER).build());
Post post = Post.builder().title("title").content("content").build();
post.confirmWriter(newMember);
Post savePost = postRepository.save(post);
//when
MvcResult result = mockMvc.perform(
get("/post/" + savePost.getId())
.characterEncoding(StandardCharsets.UTF_8)
.header("Authorization", "Bearer " + getAccessToken())
).andExpect(status().isOk()).andReturn();
PostInfoDto postInfoDto = objectMapper.readValue(result.getResponse().getContentAsString(), PostInfoDto.class);
//then
Assertions.assertThat(postInfoDto.getPostId()).isEqualTo(post.getId());
Assertions.assertThat(postInfoDto.getContent()).isEqualTo(post.getContent());
Assertions.assertThat(postInfoDto.getTitle()).isEqualTo(post.getTitle());
}
@Value("${spring.data.web.pageable.default-page-size}")
private int pageCount;
/**
* ๊ฒ์๊ธ ๊ฒ์
*/
@Test
public void ๊ฒ์๊ธ_๊ฒ์() throws Exception {
//given
Member newMember = memberRepository.save(Member.builder().username("newMEmber1123").password("!23123124421").name("123213").nickName("123").age(22).role(Role.USER).build());
final int POST_COUNT = 50;
for(int i = 1; i<= POST_COUNT; i++ ){
Post post = Post.builder().title("title"+ i).content("content"+i).build();
post.confirmWriter(newMember);
postRepository.save(post);
}
clear();
//when
MvcResult result = mockMvc.perform(
get("/post")
.characterEncoding(StandardCharsets.UTF_8)
.header("Authorization", "Bearer " + getAccessToken())
).andExpect(status().isOk()).andReturn();
//then
PostPagingDto postList = objectMapper.readValue(result.getResponse().getContentAsString(), PostPagingDto.class);
assertThat(postList.getTotalElementCount()).isEqualTo(POST_COUNT);
assertThat(postList.getCurrentPageElementCount()).isEqualTo(pageCount);
assertThat(postList.getSimpleLectureDtoList().get(0).getContent()).isEqualTo("content50");
}
}
๋ค์๋ฒ์๋ ๋๊ธ๊ณผ ๋๋๊ธ์ ์์ฑํ๊ณ ์ญ์ ํ๋ ์ปจํธ๋กค๋ฌ๋ฅผ ๊ตฌํํ๋๋ก ํ๊ฒ ์ต๋๋ค
์ ์ฒด ์ฝ๋๋ ๊นํ๋ธ์์ ํ์ธํ์ค ์ ์์ต๋๋ค.
https://github.com/ShinDongHun1/SpringBoot-Board-API