Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEAT] 4주차 테스트 코드 10개 작성 #1

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
id 'jacoco'
}

group = 'com.sopt'
Expand Down Expand Up @@ -29,10 +30,65 @@ dependencies {
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.7'

runtimeOnly 'com.h2database:h2'

}

tasks.named('test') {
useJUnitPlatform()
finalizedBy jacocoTestCoverageVerification

jacoco {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굿!

excludes += ["com/sopt/Server/controller/response/**",
"com/sopt/Server/exception/Success.class",
"com/sopt/Server/common/ApiResponse.class",
"com/sopt/Server/controller/request/**",
"com/sopt/Server/exception/model/**",
"com/sopt/Server/ServerApplication.class"]
}
}

jacoco {
toolVersion = '0.8.7'
}

jacocoTestReport {
reports {
xml.required.set(true)
csv.required.set(true)
html.required.set(true)
}

afterEvaluate {
classDirectories.setFrom(
files(classDirectories.files.collect {
fileTree(dir: it, excludes: [
"com/sopt/Server/controller/response/**",
"com/sopt/Server/exception/Success.class",
"com/sopt/Server/common/ApiResponse.class",
"com/sopt/Server/controller/request/**",
"com/sopt/Server/exception/model/**",
"com/sopt/Server/ServerApplication.class"
])
})
)
}
}

jacocoTestCoverageVerification {
violationRules {
rule {
// ...

excludes = [
'*.*Application',
'*.*Exception',
'*.DTO',
'*.response'
// ...
]
}
}
}
34 changes: 29 additions & 5 deletions src/main/java/com/sopt/Server/common/AgeEnum.java
Original file line number Diff line number Diff line change
@@ -1,22 +1,46 @@
package com.sopt.Server.common;

import static com.sopt.Server.exception.Error.*;

import com.sopt.Server.exception.Error;
import com.sopt.Server.exception.model.CustomException;
import java.util.Arrays;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;

@Getter
@AllArgsConstructor(access = AccessLevel.PRIVATE)
public enum AgeEnum {
TEENAGER("어리숙한 귀요미", "아직은 알아갈 것들이 너무 많은 당신! 세상엔 새로운 것들이 천지삐까리야~", "https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011954.png?raw=true", "https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_10.png?raw=true"),
TWENTIES("말랑한 깜찍이", "뭐가 뭔지 이제 조금 알 것 같은 당신! 앞으로도 재밌는 것들을 많이 알아가보자", "https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011951.png?raw=true","https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_20.png?raw=true"),
THIRTIES("성장중인 새싹이", "매일 매일 자라고 있는 당신! 다음 달엔 얼마나 발전했을지 궁금한 걸?", "https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011952.png?raw=true","https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_30.png?raw=true"),
FORTIES("성숙한 멋쟁이", "어디에서든 멋진 당신! 뭐든 좋으니 하고 싶은 거 다 해봐!", "https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011953.png?raw=true","https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_40.png?raw=true"),
FIFTIES("진정한 어른이", "어른이란 이런 건가 싶은 당신! 이런 식이면 진짜 어른이 될 수밖에 없어 ", "https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011955.png?raw=true","https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_50.png?raw=true");
TEENAGER(10, 19, "어리숙한 귀요미", "아직은 알아갈 것들이 너무 많은 당신! 세상엔 새로운 것들이 천지삐까리야~",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011954.png?raw=true",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_10.png?raw=true"),
TWENTIES(20, 29,"말랑한 깜찍이", "뭐가 뭔지 이제 조금 알 것 같은 당신! 앞으로도 재밌는 것들을 많이 알아가보자",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011951.png?raw=true",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_20.png?raw=true"),
THIRTIES(30, 39, "성장중인 새싹이", "매일 매일 자라고 있는 당신! 다음 달엔 얼마나 발전했을지 궁금한 걸?",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011952.png?raw=true",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_30.png?raw=true"),
FORTIES(40, 49, "성숙한 멋쟁이", "어디에서든 멋진 당신! 뭐든 좋으니 하고 싶은 거 다 해봐!",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011953.png?raw=true",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_40.png?raw=true"),
FIFTIES(50, Integer.MAX_VALUE, "진정한 어른이", "어른이란 이런 건가 싶은 당신! 이런 식이면 진짜 어른이 될 수밖에 없어 ",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Frame%2011955.png?raw=true",
"https://github.com/DO-SOPT-SOPKATHON-iOS4/SOPKATHON-Server/blob/main/image/Result_ic_50.png?raw=true");

private final int minAge;
private final int maxAge;
private final String title;
private final String content;
private final String imageUrl1;
private final String imageUrl2;

public static AgeEnum getAgeEnum(int age) {
return Arrays.stream(AgeEnum.values())
.filter(ageEnum -> ageEnum.minAge <= age && ageEnum.maxAge >= age)
.findAny()
.orElseThrow(() -> new CustomException(INVALID_AGE_ENUM, INVALID_AGE_ENUM.getMessage()));
}

Comment on lines +38 to +44
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오 이렇게 수정하셨군요!! 근데 서비스의 이해를 높여드리자면 TEENAGER의 minAge는 0살이면 좋을 것 같습니다! 10대 이하일 경우 에러를 반환하는게 아니라 그냥 10대의 결과를 반환하는게 저희 솝커톤의 서비스 흐름이었거든요!

}

Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ public class ResultController {
private final ResultService resultService;

@PostMapping("")
public ApiResponse<ResultResponseDTO> saveResult(@RequestBody AnswerListRequestDTO answerListRequestDTO){
return ApiResponse.success(Success.CREATE_RESULT_SUCCESS,resultService.saveResult(answerListRequestDTO));
public ApiResponse<ResultResponseDTO> saveResult(@RequestBody AnswerListRequestDTO answerListRequestDTO) {
return ApiResponse.success(Success.CREATE_RESULT_SUCCESS, resultService.saveResult(answerListRequestDTO));
}

@GetMapping("/{memberId}")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,8 @@

import java.util.List;

public record AnswerListRequestDTO(String nickname, List<AnswerRequestDTO> results) {
public record AnswerListRequestDTO(
String nickname,
List<AnswerRequestDTO> results
) {
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
package com.sopt.Server.controller.request;

public record AnswerRequestDTO(Long questionId, boolean answerType) {
public record AnswerRequestDTO(
Long questionId,
boolean answerType) {
}
7 changes: 7 additions & 0 deletions src/main/java/com/sopt/Server/domain/Answer.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import jakarta.persistence.*;
import lombok.AccessLevel;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -21,4 +22,10 @@ public class Answer {

private int answerScore;

@Builder
public Answer(Question question, boolean answerType, int answerScore) {
this.question = question;
this.answerType = answerType;
this.answerScore = answerScore;
}
}
20 changes: 20 additions & 0 deletions src/main/java/com/sopt/Server/domain/Member.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.sopt.Server.domain;

import static com.sopt.Server.exception.Error.INVALID_AGE;
import static com.sopt.Server.exception.Error.INVALID_NAME;

import com.sopt.Server.exception.model.CustomException;
import jakarta.persistence.*;
import java.util.regex.Pattern;
import lombok.*;

import java.util.ArrayList;
Expand All @@ -23,7 +28,22 @@ public class Member {

@Builder
public Member(String name, int realAge) {
validateName(name);
validateRealAge(realAge);

this.name = name;
this.realAge = realAge;
}

private void validateRealAge(int realAge){
if(realAge < 20 || realAge > 80){
throw new CustomException(INVALID_AGE, INVALID_AGE.getMessage());
}
}

private void validateName(String name){
if(!Pattern.matches("^[가-힣\\s]*$", name)){
throw new CustomException(INVALID_NAME, INVALID_NAME.getMessage());
}
}
}
12 changes: 11 additions & 1 deletion src/main/java/com/sopt/Server/domain/Question.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
package com.sopt.Server.domain;

import jakarta.persistence.*;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Getter
@Table(name = "QUESTIONS")
@NoArgsConstructor
public class Question {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long questionId;

private String questionContent;

public Question(String questionContent) {
this.questionContent = questionContent;
}
}
4 changes: 4 additions & 0 deletions src/main/java/com/sopt/Server/exception/Error.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ public enum Error {

// 400 BAD REQUEST
REQUEST_VALIDATION_EXCEPTION(HttpStatus.BAD_REQUEST, "잘못된 요청입니다"),
INVALID_AGE(HttpStatus.BAD_REQUEST, "나이는 20세이상부터 80세까지 가능합니다."),
INVALID_NAME(HttpStatus.BAD_REQUEST, "이름은 한글 또는 영어만 가능합니다."),
INVALID_AGE_ENUM(HttpStatus.BAD_REQUEST, "올바르지 않은 연령대 입니다."),


// 404 NOT FOUND
NOT_FOUND_MEMBER_EXCEPTION(HttpStatus.NOT_FOUND, "해당 회원을 찾을 수 없습니다"),
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/com/sopt/Server/service/MemberService.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ public class MemberService {
@Transactional
public ApiResponse<MemberGetResponse> saveMember(String nickName, int age) {
Member newMember = Member.builder().name(nickName).realAge(age).build();
Member member = memberJpaRepository.findByName(nickName).orElse(null);//null이면
if(member != null)//있다면
Member member = memberJpaRepository.findByName(nickName).orElse(null);

if(member != null)
return ApiResponse.success(Success.GET_MEMBER_SUCCESS, MemberGetResponse.of(member));
else {
memberJpaRepository.save(newMember);
Expand Down
49 changes: 25 additions & 24 deletions src/main/java/com/sopt/Server/service/ResultService.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,41 @@ public class ResultService {

@Transactional
public ResultResponseDTO saveResult(AnswerListRequestDTO request) {
Member member = memberJpaRepository.findByName(request.nickname()).orElseThrow(()->new CustomException(Error.NOT_FOUND_MEMBER_EXCEPTION,Error.NOT_FOUND_MEMBER_EXCEPTION.getMessage()));
Member member = memberJpaRepository.findByName(request.nickname()).orElseThrow(
() -> new CustomException(Error.NOT_FOUND_MEMBER_EXCEPTION,
Error.NOT_FOUND_MEMBER_EXCEPTION.getMessage()));

int memberAge = member.getRealAge();
for(AnswerRequestDTO result : request.results()){
Question question = questionJpaRepository.findById(result.questionId()).orElseThrow(()->new CustomException(Error.NOT_FOUND_QUESTION_EXCEPTION,Error.NOT_FOUND_QUESTION_EXCEPTION.getMessage()));
Answer answer = answerJpaRepository.findByQuestionAndAnswerType(question, result.answerType()).orElseThrow(()->new CustomException(Error.NOT_FOUND_ANSWER_EXCEPTION,Error.NOT_FOUND_ANSWER_EXCEPTION.getMessage()));

for (AnswerRequestDTO result : request.results()) {
Question question = questionJpaRepository.findById(result.questionId()).orElseThrow(
() -> new CustomException(Error.NOT_FOUND_QUESTION_EXCEPTION,
Error.NOT_FOUND_QUESTION_EXCEPTION.getMessage()));

Answer answer = answerJpaRepository.findByQuestionAndAnswerType(question, result.answerType()).orElseThrow(
() -> new CustomException(Error.NOT_FOUND_ANSWER_EXCEPTION,
Error.NOT_FOUND_ANSWER_EXCEPTION.getMessage()));

memberAge += answer.getAnswerScore();
}
AgeEnum ageEnum = getAgeEnum(memberAge);

AgeEnum ageEnum = AgeEnum.getAgeEnum(memberAge);
resultJpaRepository.save(Result.builder().member(member).resultAge(memberAge).build());
return ResultResponseDTO.of(request.nickname(),memberAge,ageEnum.getTitle(),ageEnum.getContent(),ageEnum.getImageUrl1(), ageEnum.getImageUrl2());

return ResultResponseDTO.of(request.nickname(), memberAge, ageEnum.getTitle(), ageEnum.getContent(),
ageEnum.getImageUrl1(), ageEnum.getImageUrl2());
}

public List<AllResultsResponseDTO> getAllResults(Long memberId) {

List<Result> resultList = resultJpaRepository.findAllByMemberIdOrderByIdDesc(memberId);
List<Result> resultList = resultJpaRepository.findAllByMemberIdOrderByIdDesc(memberId);
List<AllResultsResponseDTO> answer = new ArrayList<>();
//멤버의 result 모두 갖고옴 이것을 각각의 result마다 allresultsresponsedto만들어야 해
for(Result result : resultList) {
AgeEnum ageEnum = getAgeEnum(result.getResultAge());

for (Result result : resultList) {
AgeEnum ageEnum = AgeEnum.getAgeEnum(result.getResultAge());
String time = getStringDate(result.getTestedDate());
AllResultsResponseDTO dto = AllResultsResponseDTO.of(result, ageEnum.getTitle(), ageEnum.getContent(), time, ageEnum.getImageUrl1(), ageEnum.getImageUrl2());
AllResultsResponseDTO dto = AllResultsResponseDTO.of(result, ageEnum.getTitle(), ageEnum.getContent(), time,
ageEnum.getImageUrl1(), ageEnum.getImageUrl2());
answer.add(dto);
}

Expand All @@ -67,17 +81,4 @@ private String getStringDate(LocalDateTime time) {
return answer;
}

private AgeEnum getAgeEnum(int age){
if(age < 20)
return AgeEnum.TEENAGER;
else if(age < 30)
return AgeEnum.TWENTIES;
else if(age < 40)
return AgeEnum.THIRTIES;
else if(age < 50)
return AgeEnum.FORTIES;
else
return AgeEnum.FIFTIES;
}

}
34 changes: 34 additions & 0 deletions src/test/java/com/sopt/Server/common/AgeEnumTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.sopt.Server.common;

import static com.sopt.Server.exception.Error.INVALID_AGE_ENUM;
import static com.sopt.Server.exception.Error.INVALID_NAME;

import com.sopt.Server.exception.model.CustomException;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.Test;

public class AgeEnumTest {

@Test
void 연령Enum조회_성공_정상입력(){
// given
int age = 20;

// when
AgeEnum ageEnum = AgeEnum.getAgeEnum(age);

// then
Assertions.assertThat(ageEnum.getMinAge()).isEqualTo(20);
}

@Test
void 연령Enum조회_예외발생_연령대가10세미만인경우(){
// given
int age = 9;

// when
Assertions.assertThatThrownBy(() -> AgeEnum.getAgeEnum(age))
.isInstanceOf(CustomException.class)
.hasMessageContaining(INVALID_AGE_ENUM.getMessage());
}
}
Loading