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

[week3] 3주차 테스트 코드 10개 작성 #3

Open
wants to merge 4 commits into
base: develop
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@

import com.example.seminar.dto.request.post.PostCreateRequest;
import com.example.seminar.dto.request.post.PostUpdateRequest;
import com.example.seminar.dto.response.post.PostGetResponse;
import com.example.seminar.service.post.PostService;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
import java.util.List;

@RestController
@RequestMapping("/api/posts")
Expand All @@ -24,7 +22,7 @@ public class PostController {
public ResponseEntity<Void> createPost(
@RequestHeader(CUSTOM_AUTH_ID) Long memberId,
@RequestBody PostCreateRequest request) {
URI location = URI.create("/api/post/" + postService.create(request, memberId));
URI location = URI.create("/api/posts/" + postService.create(request, memberId));
return ResponseEntity.created(location).build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class Member extends BaseTimeEntity {
private String name;
private String nickname;
private int age;
private boolean isDeleted = false;

@Embedded
private SOPT sopt;
Expand All @@ -47,6 +48,7 @@ private Member(String name,
this.nickname = nickname;
this.age = age;
this.sopt = sopt;
this.isDeleted = false;
}

private void validateAge(final int age) {
Expand Down Expand Up @@ -74,4 +76,8 @@ private void validateNickname(final String nickname) {
public void updateSOPT(SOPT sopt) {
this.sopt = sopt;
}

public void remove() {
this.isDeleted = true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,5 @@ public record MemberCreateRequest(
int age,
SOPT sopt
) {
public MemberCreateRequest(String name, String nickname, int age, SOPT sopt) {
this.name = name;
this.nickname = nickname;
this.age = age;
this.sopt = sopt;
}

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
package com.example.seminar.dto.request.member;

import com.example.seminar.domain.Part;
import lombok.Data;

@Data
public class MemberProfileUpdateRequest {
private short generation;
private Part part;
public record MemberProfileUpdateRequest(
short generation,
Part part
) {
}

Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.seminar.repository;

import com.example.seminar.common.exception.MemberException;
import com.example.seminar.common.exception.PostException;
import com.example.seminar.domain.Member;
import com.example.seminar.domain.Post;
import org.springframework.data.jpa.repository.JpaRepository;
Expand All @@ -14,4 +16,9 @@ public interface PostJpaRepository extends JpaRepository<Post, Long> {

@Query("select p from Post p where p.member.name IN :memberName")
List<Post> findAllByMemberNameIn(List<String> memberName);

default Post findByIdOrThrow(Long id) {
return findById(id).orElseThrow(
() -> new PostException("존재하지 않는 게시글입니다."));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public String create(final MemberCreateRequest request) {
public void updateSOPT(final long memberId, final MemberProfileUpdateRequest request) {
final Member member = memberRetriever.findById(memberId);
final SOPT sopt = SOPT.builder()
.part(request.getPart())
.part(request.part())
.build();
memberUpdater.updateSOPT(member, sopt);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.example.seminar.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;

public abstract class ControllerTestManager {
@Autowired
MockMvc mockMvc;

@Autowired
ObjectMapper objectMapper;

MediaType json = MediaType.APPLICATION_JSON;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package com.example.seminar.controller;

import com.example.seminar.domain.FixtureMember;
import com.example.seminar.domain.Member;
import com.example.seminar.domain.Part;
import com.example.seminar.dto.request.member.MemberCreateRequest;
import com.example.seminar.dto.request.member.MemberProfileUpdateRequest;
import com.example.seminar.dto.request.post.PostCreateRequest;
import com.example.seminar.dto.request.post.PostUpdateRequest;
import com.example.seminar.dto.response.MemberGetResponse;
import com.example.seminar.service.member.MemberService;
import com.example.seminar.service.post.PostService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.BDDMockito;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@WebMvcTest(controllers = MemberController.class)
public class MemberControllerTest extends ControllerTestManager{

private static final String MEMBER_API_ENDPOINT = "/api/member";

@MockBean
MemberService memberService;


@Test
@DisplayName("회원을 등록한다.")
public void createMember() throws Exception {
// given
when(memberService.create(any(MemberCreateRequest.class)))
.thenReturn("1");
Member request = FixtureMember.createMember("윤정원", "garden", 26);

// when, then
mockMvc.perform(
MockMvcRequestBuilders.post(MEMBER_API_ENDPOINT)
.content(objectMapper.writeValueAsString(request))
.contentType(json))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isCreated());
}

@Test
@DisplayName("회원을 조회한다.")
public void getMember() throws Exception {
Member member = FixtureMember.createMember("윤정원", "garden", 26);

BDDMockito.given(memberService.getMemberById(1))
.willReturn(MemberGetResponse.of(member));

mockMvc.perform(MockMvcRequestBuilders.get("/api/member/1"))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("name").value("윤정원"))
.andExpect(MockMvcResultMatchers.jsonPath("age").value(26))
.andExpect(MockMvcResultMatchers.jsonPath("nickname").value("garden"));
}

// @Test
// @DisplayName("회원 정보를 수정한다.")
// void updateMember() throws Exception {
// // given
// MemberProfileUpdateRequest request = new MemberProfileUpdateRequest((short) 34, Part.WEB);
//
// // when, then
// mockMvc.perform(MockMvcRequestBuilders.patch(MEMBER_API_ENDPOINT+"/1")
// .content(objectMapper.writeValueAsString(request)))
// .andDo(MockMvcResultHandlers.print())
// .andExpect(MockMvcResultMatchers.status().isNoContent());
// }
//
// @Test
// @DisplayName("회원을 삭제한다.")
// void deleteMember() throws Exception {
// // given, when, then
// mockMvc.perform(MockMvcRequestBuilders.delete(MEMBER_API_ENDPOINT+"/1"))
// .andDo(MockMvcResultHandlers.print())
// .andExpect(MockMvcResultMatchers.status().isOk());
// }

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.example.seminar.controller;

import com.example.seminar.domain.Post;
import com.example.seminar.dto.request.post.PostCreateRequest;
import com.example.seminar.dto.request.post.PostUpdateRequest;
import com.example.seminar.repository.PostJpaRepository;
import com.example.seminar.service.post.PostService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;

import static org.junit.jupiter.api.Assertions.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

@WebMvcTest(controllers = PostController.class)
@ActiveProfiles("test")
class PostControllerTest extends ControllerTestManager {
private static final String POST_API_ENDPOINT = "/api/posts";
private static final String CUSTOM_USER_ID = "X-Auth-Id";

@MockBean
PostService postService;

@Test
@DisplayName("게시글을 등록한다.")
void createPost() throws Exception {
// given
when(postService.create(any(PostCreateRequest.class), any(Long.class)))
.thenReturn("1");
PostCreateRequest request = new PostCreateRequest("제목", "내용입니다.");


// when, then
mockMvc.perform(
MockMvcRequestBuilders.post(POST_API_ENDPOINT)
.content(objectMapper.writeValueAsString(request))
.contentType(json)
.header(CUSTOM_USER_ID, 1L))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isCreated())
.andExpect(MockMvcResultMatchers.header().string("Location", "/api/posts/1"));


}

@Test
@DisplayName("게시글을 수정한다.")
void updatePost() throws Exception {
// given
PostUpdateRequest request = new PostUpdateRequest("바꿀래");

// when, then
mockMvc.perform(MockMvcRequestBuilders.patch(POST_API_ENDPOINT+"/1")
.content(objectMapper.writeValueAsString(request)))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isNoContent());
}

@Test
@DisplayName("게시글을 삭제한다.")
void deletePost() throws Exception {
// given, when, then
mockMvc.perform(MockMvcRequestBuilders.delete(POST_API_ENDPOINT+"/1"))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import com.example.seminar.common.exception.MemberException;
import com.example.seminar.domain.FixtureMember;
import com.example.seminar.domain.Member;
import jakarta.persistence.EntityNotFoundException;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -42,9 +41,7 @@ void notFindMemberById() {
Member savedMember = memberJpaRepository.save(member);

// when, then
Assertions.assertThatThrownBy(() -> {
memberJpaRepository.findByIdOrThrow(0L);
}).isInstanceOf(MemberException.class)
Assertions.assertThatThrownBy(() -> memberJpaRepository.findByIdOrThrow(0L)).isInstanceOf(MemberException.class)
.hasMessage("존재하지 않는 회원입니다.");
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,60 @@
package com.example.seminar.repository;

import com.example.seminar.common.exception.MemberException;
import com.example.seminar.common.exception.PostException;
import com.example.seminar.domain.FixtureMember;
import com.example.seminar.domain.Member;
import com.example.seminar.domain.Post;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.test.context.ActiveProfiles;

@DataJpaTest
@ActiveProfiles("test")
public class PostJpaRepositoryTest {

@Autowired
private PostJpaRepository postJpaRepository;

@Test
@DisplayName("게시글 id를 알면 게시글을 찾을 수 있다.")
void findMemberById() {
// given
Member member = FixtureMember.createMember("정원", "garden", 26);
Post post = Post.builder()
.title("제목")
.content("내용")
.member(member)
.build();

Post savedPost = postJpaRepository.save(post);

// when
Post findPost = postJpaRepository.findByIdOrThrow(savedPost.getId());

// then
Assertions.assertThat(findPost)
.extracting("title", "content")
.containsExactly(savedPost.getTitle(), savedPost.getContent());
}

@Test
@DisplayName("존재하지 않는 회원 id를 입력할 경우 예외가 발생한다.")
void notFindMemberById() {
// given
Member member = FixtureMember.createMember("정원", "garden", 26);
Post post = Post.builder()
.title("제목")
.content("내용")
.member(member)
.build();
Post savedPost = postJpaRepository.save(post);

// when, then
Assertions.assertThatThrownBy(() -> postJpaRepository.findByIdOrThrow(0L)).isInstanceOf(PostException.class)
.hasMessage("존재하지 않는 게시글입니다.");
}
}