Server/Spring Boot
[Spring Boot] Toy Project κ²μν λ§λ€κΈ° (3) - μ‘°ν, μμ
Nellie29
2023. 12. 18. 00:28

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();
}
}