이번에는 도메인 테스트를 추가하였다.
원래 컨트롤러와 서비스단위에서만 테스트코드를 작성하였는데, 도메인도 추가하였다.
도메인 내에 있는 메서드를 테스트하였다.
코드가 너무 많기 때문에 가장 코드가 길고, 복잡한 Board를 주로 설명하겠다.
기존의 Board이다.
Board
@Entity
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class Board extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "board_id")
private Long id;
@Column(nullable = false)
private String title;
@Column(nullable = false)
@Lob
private String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id")
@OnDelete(action = OnDeleteAction.CASCADE)
private Member member;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "category_id")
@OnDelete(action = OnDeleteAction.NO_ACTION)
private Category category;
@OneToMany(mappedBy = "board",fetch = FetchType.LAZY, cascade = CascadeType.PERSIST, orphanRemoval = true)
private List<Image> images;
private int likeCount;
private int viewCount;
private boolean reportedStatus;
public Board(String title, String content, Member member,Category category, List<Image> images) {
this.title = title;
this.content = content;
this.member = member;
this.likeCount = 0;
this.viewCount = 0;
this.category = category;
this.images = new ArrayList<>();
reportedStatus = false;
addImages(images);
}
public ImageUpdatedResult update(BoardUpdateRequestDto req) {
this.title = req.getTitle();
this.content = req.getContent();
ImageUpdatedResult result = findImageUpdatedResult(req.getAddedImages(), req.getDeletedImages());
addImages(result.getAddedImages());
deleteImages(result.getDeletedImages());
onPreUpdate();
return result;
}
private void addImages(List<Image> added) {
added.forEach(i -> {
images.add(i);
i.initBoard(this);
});
}
private void deleteImages(List<Image> deleted) {
deleted.forEach(di -> this.images.remove(di));
}
private ImageUpdatedResult findImageUpdatedResult(List<MultipartFile> addedImageFiles, List<Long> deletedImageIds) {
List<Image> addedImages = convertImageFilesToImages(addedImageFiles);
List<Image> deletedImages = convertImageIdsToImages(deletedImageIds);
return new ImageUpdatedResult(addedImageFiles, addedImages, deletedImages);
}
private List<Image> convertImageIdsToImages(List<Long> imageIds) {
return imageIds.stream()
.map(id -> convertImageIdToImage(id))
.filter(i -> i.isPresent())
.map(i -> i.get())
.collect(toList());
}
private Optional<Image> convertImageIdToImage(Long id) {
return this.images.stream().filter(i -> i.getId() == (id)).findAny();
}
private List<Image> convertImageFilesToImages(List<MultipartFile> imageFiles) {
return imageFiles.stream().map(imageFile -> new Image(imageFile.getOriginalFilename())).collect(toList());
}
public void increaseLikeCount() {
this.likeCount += 1;
}
public void decreaseLikeCount() {
this.likeCount -= 1;
}
public void increaseViewCount(){
this.viewCount +=1;
}
public boolean isOwnBoard(Member member) {
return this.member.equals(member);
}
public void reportBoard(){
reportedStatus = true;
}
public void unlockReportedStatus(){
reportedStatus = false;
}
@Getter
@AllArgsConstructor
public static class ImageUpdatedResult {
private List<MultipartFile> addedImageFiles;
private List<Image> addedImages;
private List<Image> deletedImages;
}
}
기존에 있던 코드에서 네이밍만 살짝 바꾸었다.
좀 더 명확하게 나타내기 위해 현재 신고상태를 reportedStatus로 바꾸었다.
또한 신고 메서드를 reportBoard로 리네임 하였다.
나머지는 기존의 코드와 동일하다.
BoardTest
class BoardTest {
@Test
public void 신고처리_테스트() {
// given
Board board = createBoard();
board.reportBoard();
// when
boolean result = board.isReportedStatus();
// then
assertThat(result).isEqualTo(true);
}
@Test
public void 좋아요수증가_테스트() {
// given
Board board = createBoard();
// when
board.increaseLikeCount();
// then
assertThat(board.getLikeCount()).isEqualTo(1);
}
@Test
public void 좋아요수감소_테스트() {
// given
Board board = createBoard();
// when
board.increaseLikeCount();
board.decreaseLikeCount();
// then
assertThat(board.getLikeCount()).isEqualTo(0);
}
@Test
public void 조회수증가_테스트() {
// given
Board board = createBoard();
// when
board.increaseViewCount();
// then
assertThat(board.getViewCount()).isEqualTo(1);
}
@Test
public void 신고해제_테스트() {
// given
Board board = createBoard();
board.unlockReportedStatus();
// when
board.unlockReportedStatus();
boolean result = board.isReportedStatus();
// then
assertThat(result).isEqualTo(false);
}
@Test
public void 게시판작성자확인_테스트() {
//given
Member own = new Member(1l,"username","1234","name", Authority.ROLE_USER);
Board board = new Board("title", "content", own, null, List.of(new Image("a.png")));
//when,then
assertThat(board.isOwnBoard(own)).isTrue();
}
@Test
public void 게시판작성자확인_다른사람접근_테스트() {
//given
Member own = new Member(1l,"username","1234","name", Authority.ROLE_USER);
Member other = new Member(2l,"username2","12345","name2", Authority.ROLE_USER);
Board board = new Board("title", "content", own, null, List.of(new Image("a.png")));
//when,then
assertThat(board.isOwnBoard(other)).isFalse();
}
@Test
public void 게시판수정_테스트() {
// given
Image a = new Image(1l, "a", "origin_filename.jpg", null);
Image b = new Image(2l, "b", "origin2_filename.jpg", null);
List<Image> images = new ArrayList<>();
images.add(a);
images.add(b);
Board board = builder()
.title("title").content("content")
.member(createMember())
.images(images)
.build();
// when
MockMultipartFile cFile = new MockMultipartFile("c", "c.png", MediaType.IMAGE_PNG_VALUE, "cFile".getBytes());
BoardUpdateRequestDto req = new BoardUpdateRequestDto("upate title", "update content", List.of(cFile), List.of(a.getId()));
ImageUpdatedResult imageUpdatedResult = board.update(req);
// then
//제목, 내용 변경 확인
Assertions.assertThat(board.getTitle()).isEqualTo(req.getTitle());
Assertions.assertThat(board.getContent()).isEqualTo(req.getContent());
//이미지 추가, 기존 이미지 확인
List<Image> resultImages = board.getImages();
List<String> resultOriginNames = resultImages.stream().map(Image::getOriginName).collect(toList());
Assertions.assertThat(resultImages.size()).isEqualTo(2);
Assertions.assertThat(resultOriginNames).contains(b.getOriginName(), cFile.getOriginalFilename());
//이미지 삭제 확인
List<Image> deletedImages = imageUpdatedResult.getDeletedImages();
List<String> deletedOriginNames = deletedImages.stream().map(Image::getOriginName).collect(toList());
Assertions.assertThat(deletedImages.size()).isEqualTo(1);
Assertions.assertThat(deletedOriginNames).contains(a.getOriginName());
}
}
기존에 도메인에 있는 메서드의 테스트를 작성하였다.
다른 것은 다 쉬울 것이고, 아마 수정코드가 조금 복잡할 수 있다.
우선 수정의 기능에는 제목, 내용, 이미지 추가, 이미지 삭제가 있으므로
이러한 기능을 전부 테스트하였다.
이미지를 a, b를 게시판에 처음 생성 시 넣어주었다. 이유는 a를 삭제 테스트하기 위함이다.
여기서 중요한 점은 images를 따로 만들어주었다는 것이다.
이유는 보드 생성 시 builder에서 List.of로 생성하게 되면, 이후 아래 삭제 로직에서 에러가 발생한다.
이유는 List.of로 설정한 값은 수정하면 안 되기 때문이다.
주석에 given, when, then으로 나누었는데 이는 각각 아래와 같은 의미라 생각하면 편하다.
- given은 테스트에 필요한 값을 세팅
- when은 테스트에 실행
- then은 검증
도메인 테스트의 결과
'프로젝트 > 커뮤니티' 카테고리의 다른 글
[프로젝트] 커뮤니티 REST API 서버만들기 #9 카테고리 API 만들기 (0) | 2023.01.29 |
---|---|
[프로젝트] 커뮤니티 REST API 서버만들기 #8 어드민 페이지 만들기 (4) | 2023.01.28 |
[프로젝트] 커뮤니티 REST API 서버만들기 #7 Report API 만들기 (0) | 2023.01.27 |
[프로젝트] 커뮤니티 REST API 서버만들기 #6 Comment API만들기 (0) | 2023.01.25 |
[프로젝트] 커뮤니티 REST API 서버만들기 #5 게시판 부가기능 추가 (0) | 2023.01.24 |