프론트엔드 4명과 백엔드 3명으로 구성되었다.
스택오버플로우 클론 코딩
추후 개발하며 수정 예정
package com.mzdevelopers.serverapplication.question.service;
import com.mzdevelopers.serverapplication.question.entity.Question;
import com.mzdevelopers.serverapplication.question.repository.QuestionRepository;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.Optional;
import static org.mockito.Mockito.*;
class QuestionServiceImplTest {
@Mock
private QuestionRepository questionRepository;
private QuestionServiceImpl questionService;
@BeforeEach
public void setUp() {
MockitoAnnotations.openMocks(this);
questionService = new QuestionServiceImpl(questionRepository);
}
public Question makeQuestion(String title, String detail, Long memberId) {
return Question.builder().title(title).detail(detail).memberId(memberId).build();
}
@Test
@DisplayName("질문 생성 성공")
void creatQuestion_Success() {
// given
String title = "이거 너무 어려워요";
String detail = "간단한거지만 너무 어렵에요";
Question question = makeQuestion(title, detail, 1L);
// when
when(questionRepository.save(question)).thenReturn(question);
// then
Question saveQuestion = questionRepository.save(question);
Assertions.assertNull(saveQuestion.getQuestionId());
Assertions.assertEquals(title, saveQuestion.getTitle());
Assertions.assertEquals(detail, saveQuestion.getDetail());
}
@Test
@DisplayName("질문 가져오기 성공")
void getQuestion_Success() {
String title = "title";
String detail = "detail";
Question question = makeQuestion(title, detail, 1L);
// when
when(questionRepository.findById(question.getQuestionId())).thenReturn(Optional.of(question));
Optional<Question> optionalQuestion = questionService.findByQuestionId(question.getQuestionId());
// then
Question find = optionalQuestion.get();
Assertions.assertEquals(find.getDetail(), detail);
Assertions.assertEquals(find.getTitle(), title);
Assertions.assertEquals(find.getQuestionId(), question.getQuestionId());
}
@Test
@DisplayName("질문 가져오기 실패 - 잘못된 질문 ID")
void getQuestion_Failure(){
// given
Long invalidQuestionId = 2L;
// when
when(questionRepository.findById(invalidQuestionId)).thenReturn(Optional.empty());
// then
Optional<Question> question = questionService.findByQuestionId(invalidQuestionId);
Assertions.assertFalse(question.isPresent());
}
@Test
@DisplayName("질문 수정 성공")
void updateQuestion_Success() {
// given
Long questionId = 1L;
String title = "title";
String detail = "detail";
String updateTitle = "title2";
String updateDetail = "detail2";
Question save = makeQuestion(title, detail, 1L);
// when
when(questionRepository.save(save)).thenReturn(save);
Question saveQuestion = questionRepository.save(save);
when(questionRepository.findById(questionId)).thenReturn(Optional.of(saveQuestion));
Optional<Question> optionalQuestion = questionService.findByQuestionId(questionId);
Question findQuestion = optionalQuestion.get();
findQuestion.update(updateTitle, updateDetail);
when(questionRepository.save(findQuestion)).thenReturn(findQuestion);
// then
Optional<Question> assertQuestion = questionService.findByQuestionId(questionId);
Assertions.assertTrue(assertQuestion.isPresent());
Assertions.assertEquals(updateDetail, assertQuestion.get().getDetail());
Assertions.assertEquals(updateTitle, assertQuestion.get().getTitle());
Assertions.assertNotEquals(title, saveQuestion.getTitle());
Assertions.assertNotEquals(detail, saveQuestion.getDetail());
}
@Test
@DisplayName("질문 수정 실패 - 잘못된 질문 ID")
void updateQuestion_Failure_Invalid_Id() {
// given
Long invalidQuestionId = 2L;
String title = "title";
String detail = "detail";
Question save = makeQuestion(title, detail, 1L);
// when
when(questionRepository.save(save)).thenReturn(save);
questionRepository.save(save);
when(questionRepository.findById(invalidQuestionId)).thenReturn(Optional.empty());
// then
Optional<Question> findQuestion = questionService.findByQuestionId(invalidQuestionId);
Assertions.assertFalse(findQuestion.isPresent());
}
@Test
@DisplayName("질문 삭제 성공")
void deleteQuestion() {
// given
Long questionId = 1L;
Question question = makeQuestion("title", "detail", 1L);
// when
when(questionRepository.findById(questionId)).thenReturn(Optional.of(question));
Optional<Question> findQuestion = questionService.findByQuestionId(questionId);
doNothing().when(questionRepository).delete(findQuestion.get());
// then
Assertions.assertDoesNotThrow(() -> questionService.deleteQuestion(questionId));
}
}
개발 기간이 총 2주가 되지 않아 5일정도 기획을 진행하였다.
처음 프론트엔드 분들과 협업을 하는거라 기획에 어려움을 느꼈다.
어찌저찌 요구사항 정의서, DB Diagram, API 명세서등을 작성하고 현재 개발에 들어갔다.
솔로 프로젝트일땐 변경사항이 있으면 그때그때 생각나는대로 수정, 변경하였지만 협업을 해보니 이 부분이 쉽지않음을 또 느낀다.
또 처음 Git을 통해 branch, kanban, issue, pr 등을 접하고 공부해보니 처음엔 어려웠고 많은 오류들도 많았는데 삽질을 시원하게 하고 나니 어느정도 가닥이 잡혀 잘 진행중이다.
백엔드 분들과 각자 기능을 맡아 진행하였고, TDD 방식으로 진행을 해보고 싶어 따로 테스트 코드들을 작성하고, 구현 코드로 옮기는 연습을 하며 진행중이다.
처음엔 테스트 코드를 작성하고, 왜 구현 코드보다 먼저 작성해야하는지 의문점과 불편함은 말로 표현을 못할정도로 나에겐 맞지 않았다. 하지만 하다보니 테스트 코드를 통해 내 코드에 대한 확실성을 느꼈고, 동작의 흐름을 명확하게 이해했다. 평소같으면 이리저리 클래스를 옮겨가며 작성하여, 내 코드를 까먹는 경우도 많았다. 하지만 테스트 코드를 작성하고 이 코드가 가이드라인 되어 구현 코드를 작성하는 것에 도움을 많이 주었다. 또한 작성하며 가독성과 중복성을 생각해 더 좋은 코드를 작성하는 것 같았다.
이것으로 Pre-Project 개발 일지 1일차 완료.