Skip to content
Merged
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
6 changes: 3 additions & 3 deletions plan/4.3. study_plan-week-3-summary.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@
- **3.1.4.** ManyToOne, OneToMany 사용
- **3.2.** Spring Boot 테스트 코드 작성
- **3.2.1.** 단위 테스트 (Unit Test) 작성
- **3.2.1.1.** 테스트 관점에서의 Request, Response DTO 클래스 작성의 필요성
- MockMvc 사용
- 테스트 관점에서의 Request, Response DTO 클래스 작성의 필요성
- **3.2.2.** 통합 테스트 (Integration Test) 작성
- **3.2.3.** MockMvc 사용
- **3.3.** RESTful API 설계 및 구현
- **3.3.1.** RESTful API 기본 원칙
- **3.3.1.1.** 데이터 전송 관점에서의 Request, Response DTO 클래스 작성
- 데이터 전송 관점에서의 Request, Response DTO 클래스 작성의 필요성
- **3.3.3.** API 예외 처리
- **3.3.4.** Spring Validation 사용
- **3.3.5.** Converter 사용
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@EnableJpaAuditing
@SpringBootApplication
public class Application {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.mpc.springboot.config.audit;

import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;

@EnableJpaAuditing
@Configuration
public class AuditingConfiguration {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.mpc.springboot.member.application.dto;

import com.mpc.springboot.member.domain.entity.Member;
import com.mpc.springboot.member.domain.vo.MemberCode;
import com.mpc.springboot.member.domain.vo.MemberName;
import lombok.*;

@Getter
@RequiredArgsConstructor(access = AccessLevel.PROTECTED)
public class MemberResponse {
private final MemberCode code;
private final MemberName name;

public static MemberResponse from(Member member) {
return new MemberResponse(member.getCode(), member.getName());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import jakarta.transaction.Transactional;

import org.springframework.stereotype.Service;
import com.mpc.springboot.member.application.dto.MemberResponse;
import com.mpc.springboot.member.domain.entity.Member;
import com.mpc.springboot.member.domain.exception.MemberNotFoundException;
import com.mpc.springboot.member.domain.repository.MemberRepository;
Expand All @@ -15,9 +16,10 @@ public class MemberService {

private final MemberRepository memberRepository;

public Member getMemberBy(MemberCode code) {
return memberRepository.findMemberBy(code)
.orElseThrow(MemberNotFoundException::new);
public MemberResponse getMemberBy(MemberCode code) {
Member member = memberRepository.findMemberBy(code)
.orElseThrow(MemberNotFoundException::new);
return MemberResponse.from(member);
}

@Transactional
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import com.mpc.springboot.member.application.dto.MemberResponse;
import com.mpc.springboot.member.application.service.MemberService;
import com.mpc.springboot.member.domain.entity.Member;
import com.mpc.springboot.member.domain.vo.MemberCode;
Expand All @@ -15,7 +16,7 @@ public class MemberRestController {
private final MemberService memberService;

@GetMapping("/{code}")
public ResponseEntity<Member> getMemberBy(@PathVariable MemberCode code) {
public ResponseEntity<MemberResponse> getMemberBy(@PathVariable MemberCode code) {
return ResponseEntity.ok(memberService.getMemberBy(code));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.mpc.springboot.member.presentation.controller;

import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import com.mpc.springboot.member.application.dto.MemberResponse;
import com.mpc.springboot.member.application.service.MemberService;
import com.mpc.springboot.member.domain.entity.Member;
import com.mpc.springboot.member.domain.repository.MemberRepository;
import com.mpc.springboot.member.domain.vo.MemberCode;
import com.mpc.springboot.member.domain.vo.MemberName;
import com.mpc.springboot.shared.AbstractControllerTest;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@WebMvcTest(MemberRestController.class)
class MemberRestControllerTest extends AbstractControllerTest {

@MockitoBean
private MemberService memberService;

/**
* @see MemberRestController#getMemberBy(MemberCode)
*/
@DisplayName("회원 조회: 회원 코드로 조회")
@Test
void getMemberBy() throws Exception {
// given
MemberCode code = MemberCode.of("M0000003");
MemberName name = MemberName.of("John", "Doe");
Member member = Member.of(code, name);
MemberResponse memberResponse = MemberResponse.from(member);
given(memberService.getMemberBy(any())).willReturn(memberResponse);

// when & then
mockMvc.perform(get("/api/v1/members/{code}", code.getValue()))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code.value").value(code.getValue()))
.andExpect(jsonPath("$.name.firstName").value(name.getFirstName()))
.andExpect(jsonPath("$.name.lastName").value(name.getLastName()))
.andExpect(jsonPath("$.name.fullName").value(name.getFullName()));

}

@Test
void createMember() {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.mpc.springboot.shared;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.test.web.servlet.MockMvc;

@WebMvcTest
@AutoConfigureMockMvc
public abstract class AbstractControllerTest {

@Autowired
protected MockMvc mockMvc;
}