1๏ธโฃ ResponseDto ์์ฑ
๐ BoardReadDto
- ๊ฒ์๊ธ ๋จ๋ ์กฐํ ์ ์ฌ์ฉ
package com.gdsc_teamb.servertoyproject.dto.boardDto;
import com.gdsc_teamb.servertoyproject.domain.post.domain.PostEntity;
import com.gdsc_teamb.servertoyproject.domain.user.domain.UserEntity;
import lombok.Getter;
// ๊ฒ์๊ธ ์กฐํ ์ ์ฌ์ฉ
@Getter
public class BoardReadDto {
private Long id; // ๊ฒ์๊ธ ID
private String title; // ๊ฒ์๊ธ ์ ๋ชฉ
private String content; // ๊ฒ์๊ธ ๋ด์ฉ
private String nickname; // ์์ฑ์ ์ ๋ณด
// BoardReadDto ์ ์์ฑ์
public BoardReadDto(PostEntity entity){
this.id=entity.getId();
this.content=entity.getContent();
this.title=entity.getTitle();
this.nickname=entity.getUser().getNickname();
}
}
๐ BoardListDto
- ๊ฒ์๊ธ ๋ชฉ๋ก ์กฐํ ์ ์ฌ์ฉ
package com.gdsc_teamb.servertoyproject.dto.boardDto;
import com.gdsc_teamb.servertoyproject.domain.post.domain.PostEntity;
import com.gdsc_teamb.servertoyproject.domain.user.domain.UserEntity;
import lombok.Getter;
import java.time.LocalDateTime;
// ๊ฒ์๊ธ ๋ชฉ๋ก ์กฐํ ์ ์ฌ์ฉ
@Getter
public class BoardListDto {
private Long id; // ๊ฒ์๊ธ ID
private String title; // ๊ฒ์๊ธ ์ ๋ชฉ
private String nickname; // ์์ฑ์ ๋๋ค์
private LocalDateTime updated_at; // ์์ ์ผ์
// BoardListDto ์ ์์ฑ์
public BoardListDto(PostEntity entity){
this.id=entity.getId();
this.title=entity.getTitle();
this.nickname=entity.getUser().getNickname(); // UserEntity ์์ nickname ๊ฐ์ ธ์ค๊ธฐ
this.updated_at=entity.getUpdated_at();
}
}
2๏ธโฃ Service ์์ฑ
๐ BoardService
package com.gdsc_teamb.servertoyproject.service;
import com.gdsc_teamb.servertoyproject.domain.post.domain.PostEntity;
import com.gdsc_teamb.servertoyproject.domain.repository.PostRepository;
import com.gdsc_teamb.servertoyproject.domain.user.domain.UserEntity;
import com.gdsc_teamb.servertoyproject.domain.user.domain.UserRepository;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardDto;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardListDto;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardReadDto;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardUpdateDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
@RequiredArgsConstructor
public class BoardService {
private final PostRepository postRepository;
private final UserRepository userRepository;
@Transactional
public ResponseEntity<Object> findById (Long id) {
try {
// boardRepository ์์ ์ฃผ์ด์ง id์ ํด๋นํ๋ ๊ฒ์๊ธ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํ
PostEntity post = postRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException());
return ResponseEntity.ok(new BoardReadDto(post));
} catch (Exception e) {
return ResponseEntity.badRequest().body("๊ฒ์๊ธ ์กฐํ์ ์คํจํ์ต๋๋ค. " + e.getMessage());
}
}
@Transactional (readOnly=true)
public List<BoardListDto> findAllByOrderByIdDesc(){
return postRepository.findAllByOrderByIdDesc().stream()
// BoardRepository ์ findAllDesc ๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ ๊ฒ์๊ธ์ ๋ด๋ฆผ์ฐจ์์ผ๋ก ์กฐํ (์ฟผ๋ฆฌ ๊ธฐ๋ฅ)
.map(BoardListDto::new)// ๊ฐ ๊ฒ์๊ธ์ BoardListDto ๋ก ๋ณํ
.collect(Collectors.toList()); // ์ดํ ๋ฆฌ์คํธ๋ก ์์งํ์ฌ ๋ฐํ
}
@Transactional
public ResponseEntity<Object> deletePost(Long id){
try{
// boardRepository ์์ ์ฃผ์ด์ง id์ ํด๋นํ๋ ๊ฒ์๊ธ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์กฐํ
PostEntity post= postRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("ํด๋น ๊ฒ์๊ธ์ด ์์ต๋๋ค. id="+id));
// JpaRepository ์์ ๊ธฐ๋ณธ ์ ๊ณต๋๋ delete ๋ฉ์๋
// ์ฃผ์ด์ง post ์ํฐํฐ๋ฅผ ๋ฐ์ดํฐ๋ฒ ์ด์ค์์ ์ญ์ ํ๋ ์ญํ
postRepository.delete(post);
return ResponseEntity.ok("๊ฒ์๊ธ์ด ์ฑ๊ณต์ ์ผ๋ก ์ญ์ ๋์์ต๋๋ค.");
}catch (Exception e){
return ResponseEntity.badRequest().body("๊ฒ์๊ธ ์ญ์ ์ ์คํจํ์ต๋๋ค. " + e.getMessage());
}
}
}
๐ findById()
- ๊ฒ์๊ธ ์ธ๋ถ ๋ด์ฉ ์กฐํ
- id๋ ์กฐํํ ๊ฒ์๊ธ์ ID๋ฅผ ๋ด์
- ์กฐํ๋ ๊ฒ์๊ธ์ ์ธ๋ถ ๋ด์ฉ์ ๋ด์ BoardReadDto๋ฅผ return
๐ findAllByOrderByIdDesc()
- ๊ฒ์๊ธ ๋ชฉ๋ก ์กฐํ
- ๊ฒ์๊ธ ๋ชฉ๋ก์ ๋ด์ List<BoardListDto> return
๐ deletePost()
- ๊ฒ์๊ธ ์ญ์
- id๋ ์ญ์ ํ ๊ฒ์๊ธ์ ID
3๏ธโฃ Controller ์์ฑ
๐ BoardController
package com.gdsc_teamb.servertoyproject.controller;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardDto;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardListDto;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardReadDto;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardUpdateDto;
import com.gdsc_teamb.servertoyproject.service.BoardService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequiredArgsConstructor
public class BoardController {
private final BoardService boardService;
@GetMapping("/api/boards/{id}")
public ResponseEntity<Object> findById (@PathVariable Long id){
return boardService.findById(id);
}
@GetMapping("/api/boards")
public List<BoardListDto> findAllDesc() {
return boardService.findAllByOrderByIdDesc();
}
@DeleteMapping("/api/boards/{id}")
public Long delete(@PathVariable Long id){
boardService.deletePost(id);
return id;
}
}
๐ findById()
- HTTP GET ์์ฒญ์ ํตํด ํน์ ID์ ๊ฒ์๊ธ์ ์กฐํ
- ๋งค๊ฐ๋ณ์: ์กฐํํ ๊ฒ์๊ธ์ ID๋ฅผ ์ ๋ฌ๋ฐ์
- @PathVariable์ ํตํด ๊ฒฝ๋ก์์ ์ถ์ถ๋ ๊ฒ์๊ธ์ ID๋ฅผ ์ ๋ฌ ๋ฐ์
- ๋ฐํ ๊ฐ: ์กฐํ๋ ๊ฒ์๊ธ์ ์ธ๋ถ ์ ๋ณด๊ฐ ๋ด๊ธด DTO๋ฅผ ๋ฐํ
๐ findAllDesc()
- HTTP GET ์์ฒญ์ ํตํด ๋ชจ๋ ๊ฒ์๊ธ ๋ชฉ๋ก์ ์กฐํ
- ๋ฐํ ๊ฐ: ์กฐํ๋ ๋ชจ๋ ๊ฒ์๊ธ์ ๋ชฉ๋ก์ด ๋ด๊ธด DTO ๋ค์ ๋ฆฌ์คํธ๋ก ๋ฐํ
๐ delete()
- HTTP DELETE ์์ฒญ์ ํตํด ํน์ ID์ ๊ฒ์๊ธ์ ์ญ์
- ๋งค๊ฐ๋ณ์: ์ญ์ ํ ๊ฒ์๊ธ์ ID๋ฅผ ์ ๋ฌ ๋ฐ์
- @PathVariable ์ ํตํด ๊ฒฝ๋ก์์ ์ถ์ถ๋ ๊ฒ์๊ธ์ ID๋ฅผ ์ ๋ฌ ๋ฐ์
- ๋ฐํ ๊ฐ: ์ญ์ ๊ฐ ์๋ฃ๋ ๊ฒ์๊ธ์ ID๋ฅผ ๋ฐํ
4๏ธโฃ TestCode
๐ BoardControllerTest
- ๊ฒ์๊ธ ์ญ์ ํต์ ์ด ์ ์ด๋ฃจ์ด์ง๋์ง์ ๋ํ ํ ์คํธ ์ฝ๋
- MocMvc ์ฌ์ฉํ์ฌ ํต์
package com.gdsc_teamb.servertoyproject.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gdsc_teamb.servertoyproject.domain.post.domain.HeartEntity;
import com.gdsc_teamb.servertoyproject.domain.post.domain.PostEntity;
import com.gdsc_teamb.servertoyproject.domain.repository.PostRepository;
import com.gdsc_teamb.servertoyproject.domain.user.domain.UserRepository;
import com.gdsc_teamb.servertoyproject.domain.user.domain.UserEntity;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardDto;
import com.gdsc_teamb.servertoyproject.dto.boardDto.BoardUpdateDto;
import jakarta.transaction.Transactional;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.http.*;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.test.util.AssertionErrors.fail;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@Transactional
class BoardControllerTest {
// ํ
์คํธ์ ์ฌ์ฉํ ์๋ฒ์ ๋๋ค ํฌํธ ๋ฒํธ๋ฅผ ํ ๋น
@LocalServerPort
private int port;
@Autowired
private PostRepository postRepository;
@Autowired
private UserRepository userRepository;
@Autowired
private MockMvc mockMvc;
@Test
@DisplayName("๊ฒ์๋ฌผ ์ญ์ ํ
์คํธ")
public void deletePost() throws Exception{
UserEntity savedUser = userRepository.save(UserEntity.builder()
.email("abc@abc.com")
.password("password1234")
.nickname("nickname")
.phone("01012345678")
.build());
PostEntity savedPost = postRepository.save(PostEntity.builder()
.title("title")
.content("content")
.user(savedUser)
.build());
Long deleteId = savedPost.getId();
String url="http://localhost:" + port + "/api/boards/"+deleteId;
// when
mockMvc.perform(delete(url))
.andExpect(status().isOk());
// then
// ์ญ์ ํ ๋ฐ์ดํฐ ์กฐํ
Optional<PostEntity> deletedPost = postRepository.findById(savedPost.getId());
assertThat(deletedPost).isNotPresent();
}
}