Skip to content

Commit

Permalink
#24 - 게시글 서비스 로직의 테스트와 골격 잡기
Browse files Browse the repository at this point in the history
* 게시글 검색하면 게시글 리스트 반환
* 게시글을 ID로 조회
* 게시글 생성
* 게시글 수정
* 게시글 삭제

* 수정 필요
필요한 dto 와 enum을 함께 작성했는데 반영 해야함
  • Loading branch information
rhakdnj committed Aug 9, 2022
1 parent f02c396 commit 4e04f31
Show file tree
Hide file tree
Showing 5 changed files with 170 additions and 0 deletions.
@@ -0,0 +1,5 @@
package com.example.boardproject.domain.type;

public enum SearchType {
TITLE, CONTENT, ID, NICKNAME, HASHTAG
}
20 changes: 20 additions & 0 deletions src/main/java/com/example/boardproject/dto/ArticleDto.java
@@ -0,0 +1,20 @@
package com.example.boardproject.dto;

import java.time.LocalDateTime;

public record ArticleDto(
LocalDateTime createdAt,
String createdBy,
String title,
String content,
String hashtag
) {
public static ArticleDto of(LocalDateTime createdAt,
String createdBy,
String title,
String content,
String hashtag) {
return new ArticleDto(createdAt, createdBy, title, content, hashtag);
}

}
11 changes: 11 additions & 0 deletions src/main/java/com/example/boardproject/dto/ArticleUpdateDto.java
@@ -0,0 +1,11 @@
package com.example.boardproject.dto;

public record ArticleUpdateDto(
String title,
String content,
String hashtag
) {
public static ArticleUpdateDto of(String title, String content, String hashtag) {
return new ArticleUpdateDto(title, content, hashtag);
}
}
37 changes: 37 additions & 0 deletions src/main/java/com/example/boardproject/service/ArticleService.java
@@ -0,0 +1,37 @@
package com.example.boardproject.service;

import com.example.boardproject.domain.type.SearchType;
import com.example.boardproject.dto.ArticleDto;
import com.example.boardproject.dto.ArticleUpdateDto;
import com.example.boardproject.repository.ArticleRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Transactional
@Service
public class ArticleService {

private final ArticleRepository articleRepository;

@Transactional(readOnly = true)
public Page<ArticleDto> searchArticles(SearchType title, String searchKeyword) {
return Page.empty();
}

@Transactional(readOnly = true)
public ArticleDto searchArticle(long articleId) {
return null;
}

public void saveArticle(ArticleDto dto) {
}

public void updateArticle(long articleId, ArticleUpdateDto dto) {
}

public void deleteArticle(long articleId) {
}
}
@@ -0,0 +1,97 @@
package com.example.boardproject.service;

import com.example.boardproject.domain.Article;
import com.example.boardproject.domain.type.SearchType;
import com.example.boardproject.dto.ArticleDto;
import com.example.boardproject.dto.ArticleUpdateDto;
import com.example.boardproject.repository.ArticleRepository;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.data.domain.Page;

import java.time.LocalDateTime;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.*;

@DisplayName("비즈니스 로직 - 게시글")
@ExtendWith(MockitoExtension.class)
class ArticleServiceTest {

// sut: system under test
// @InjectMocks 은 온전히 생성자 주입은 어려움 Target: Field
@InjectMocks
private ArticleService sut;

@Mock
private ArticleRepository articleRepository;

@DisplayName("게시글을 검색하면, 게시글 리스트로 반환한다.")
@Test
void givenSearchParameters_whenSearchingArticles_thenReturnsArticleList() {
// Given

// When
Page<ArticleDto> articles = sut.searchArticles(SearchType.TITLE, "search keyword");

// Then
assertThat(articles).isNotNull();
}

@DisplayName("게시글을 조회하면, 게시글을 반환한다.")
@Test
void givenId_whenSearchingArticle_thenReturnsArticle() {
// Given

// When
ArticleDto article = sut.searchArticle(1L);

// Then
assertThat(article).isNotNull();
}

@DisplayName("게시글을 정보를 입력하면, 게시글을 생성한다.")
@Test
void givenArticleInfo_whenSavingArticle_thenSavesArticle() {
// Given
given(articleRepository.save(any(Article.class))).willReturn(null);

// When
sut.saveArticle(ArticleDto.of(LocalDateTime.now(), "Jm", "title", "content", "hashtag"));

// Then
then(articleRepository).should().save(any(Article.class));
}

@DisplayName("게시글을 ID와 수정 정보를 입력하면, 게시글을 수정한다.")
@Test
void givenArticleIdAndModifiedInfo_whenUpdatingArticle_thenUpdatesArticle() {
// Given
given(articleRepository.save(any(Article.class))).willReturn(null);

// When
sut.updateArticle(1L, ArticleUpdateDto.of("title", "content", "#java"));

// Then
then(articleRepository).should().save(any(Article.class));
}

@DisplayName("게시글을 ID를 입력하면, 게시글을 삭제한다.")
@Test
void givenArticleId_whenDeletingArticle_thenDeletesArticle() {
// Given
willDoNothing().given(articleRepository).delete(any(Article.class));

// When
sut.deleteArticle(1L);

// Then
then(articleRepository).should().delete(any(Article.class));
}

}

0 comments on commit 4e04f31

Please sign in to comment.