Pre-Project 개발 시작

김준영·2023년 6월 14일
1

Pre-Project

목록 보기
1/3
post-thumbnail

프로젝트 내용


개발 인원

프론트엔드 4명과 백엔드 3명으로 구성되었다.

프로젝트 주제

스택오버플로우 클론 코딩

협업 & 형상 관리

  • Github
  • Discord
  • Github kanban
  • Notion

백엔드 기술 스택

  • java 11
  • Spring Boot 2.7.12
  • MySQL & H2
  • AWS

사용자 요구 사항 정의서 작성


DB Diagram


API 명세서



추후 개발하며 수정 예정

테스트 코드


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일차 완료.

profile
ㅎㅎ

0개의 댓글