๋ฐ์ํ
@Service
- ํด๋ src-main-java-hello-hellspring์์ serviceํจํค์ง์ MemberService ํด๋์ค.
- ํด๋์ค ์์ @Service๋ฅผ ์ ์ด์ค๋ค.
- ์๋น์ค ์ฝ๋ฉ
- ์ฝ๋
์๋ ์ ์ฒด์ฝ๋๋ ํฌ์คํธ์ ๋ด์ฉ์ ๋ชจ๋ ๋ฐ์ํ ์ฝ๋๋ก ์ด ์บก์ฒ๋ณธ๊ณผ ๋ค๋ฆ ๋๋ค. - ์ ์ฒด์ฝ๋
๋๋ณด๊ธฐ
package hello.hellospring.service; import java.util.List; import java.util.Optional; import org.springframework.stereotype.Service; import hello.hellospring.domain.Member; import hello.hellospring.repository.MemberRepository; @Service public class MemberService { private final MemberRepository memberRepository; public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; } /** * ํ์ ๊ฐ์ * @param member * @return ํ์id */ public Long join(Member member) { validateDuplicateMember(member); // ์ค๋ณต ํ์ ๊ฒ์ฆ memberRepository.save(member); return member.getId(); } private void validateDuplicateMember(Member member) { memberRepository.findByName(member.getName()) .ifPresent(m -> { throw new IllegalStateException("์ด๋ฏธ ์กด์ฌํ๋ ํ์์ ๋๋ค."); }); } /** * ์ ์ฒด ํ์ ์กฐํ * @return ์ ์ฒดํธ์๋ฆฌ์คํธ */ public List<Member> findMembers() { return memberRepository.findAll(); } public Optional<Member> findOne(Long memberId) { return memberRepository.findById(memberId); } }
- private final MemberRepository memberRepository = new MemoryMemberRepository();
- private final
→ ํด๋์ค์์๋ง ์์๋ก ์ฌ์ฉํ ์ ์๋ - MemberRepository memberRepository = new MemoryMemberRepository();
→ ๋ฆฌํฌ์งํ ๋ฆฌ ์ธํฐํ์ด์ค๋ฅผ ํ์ ์ผ๋ก ํ๋ ๊ตฌํํด๋์ค ์ธํฐํ์ด์ค๋ฅผ ๋ง๋ญ๋๋ค.
- private final
- Optional ์ค๋ช
memberRepository.findByName(member.getName()) .ifPresent(m -> { throw new IllegalStateException("์ด๋ฏธ ์กด์ฌํ๋ ํ์์ ๋๋ค."); });
- memberRepository.findByName(member.getName()) : ๋ฉค๋ฒ์ด๋ฆ์ ์ฐพ์ Optional์ ๋ฐํํฉ๋๋ค.
- ๋ฐ๋ผ์ ๊ทธ ๋ค์ ์ฝ๋๋ค์ ๋ชจ๋ Optional์ ๋ฉ์๋๋ค ์
๋๋ค.
- Optional์ isPresent()ํจ์๋ฅผ ์ด์ฉํด ๊ฐ์ด ์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์ ์ํต๋๋ค.
- ..ifPresent(m -> { throw... : Optional์ ํ์์ด ์์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์์ํต๋๋ค.
- memberRepository.findByName(member.getName()) : ๋ฉค๋ฒ์ด๋ฆ์ ์ฐพ์ Optional์ ๋ฐํํฉ๋๋ค.
- ์ฝ๋
- ๋๋จธ์ง๋ Rrepository์ ๋ฉ์๋๋ฅผ ์ด์ฉํ๊ธฐ ๋๋ฌธ์ ์ค๋ช ์ ์๋ตํ๊ฒ ์ต๋๋ค.
โป ์๋น์ค์ ํด๋์ค์ ํจ์๋ช ์ ๋น์ง๋์ค์ ๊ฐ๊น๊ฒ ์ด๋ฆ์ ์ง๋๋ค.
- ๊ถ์ฅ ์ฝ๋ ์์ฑ๋ฒ
- ์๋ ์ฝ๋์ ๊ฒฝ์ฐ Optional์ ๋ณ์๋ก ๋ฐํ ๋ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์๋๋ค.
- Optional์ isPresent()ํจ์๋ฅผ ์ด์ฉํด ๊ฐ์ด ์์ผ๋ฉด ์์ธ๋ฅผ ๋ฐ์ ์ํต๋๋ค.
- ์ด๋ ๊ฒ ์ฝ๋๊ฐ ๊ธธ์ด์ง ๊ฒฝ์ฐ
- ์๋ ์ฝ๋์ ๊ฒฝ์ฐ Optional์ ๋ณ์๋ก ๋ฐํ ๋ฐ์ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅ๋์ง ์๋๋ค.
Test
ํ ์คํธ์ ๊ตฌ์กฐ์ ์ฌ์ฉ๋ฒ์ ์ด์ ํธ์ ์ฐธ๊ณ ํด์ฃผ์ธ์.
๊ทธ๋ฆฌ๊ณ ์ด๋ฒ ํฌ์คํธ๋ ์๋์์ฑ ๊ธฐ๋ฅ์ ์ด์ฉํ์ต๋๋ค.
2025.01.05 - [๐ ๋๊ตฌ/โฐ Visual Studio Code] - [VScode]ํ ์คํธ ์๋์์ฑ source action
given / when / then
- given : ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ณ
- when : ๊ธฐ๋ฅ์ ์คํํ๊ณ
- then : ๊ฒฐ๊ณผ๊ฐ ์ด๋ป๊ฒ ๋์๋ ์ง ํ์ธํ๋ ์์๋ก ์ฝ๋๋ฅผ ์์ฑํ๋ค.
์ค๋ฅ ๋ฐ์ ์ํค๊ธฐ
- ์ค๋ณตํ์์ ๊ฒ์ฆํ๋ validateDuplicateMember๋ฉ์๋๋ฅผ ์ด์ฉํด ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ค ํ๋ค.
- ์ค๋ณต ํ
์คํธ ์ฝ๋
- ์ฝ๋
- ๋ฉค๋ฒ ๋๋ฉ์ธ์ ์ค๋ณต๋ ์ด๋ฆ์ผ๋ก ๋๊ฐ ๋ง๋ค์๋ค.
- ์ค๋ณต ๊ฐ์
์ ๋ฐ์์ํจ๋ค.
- ์ด ๋ ์ค๋ฅ๋ฅผ try/catch๋ฌธ์ ํตํด ์ฒ๋ฆฌํ ์ ์๋ค.
- catch๋ถ๋ถ์ด ์กฐ๊ธ ํฅ๋ฏธ๋กญ๋ค.
} catch (IllegalStateException e) { assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์ฌํ๋ ํ์์ ๋๋ค.12341234"); }
- catch๋ก ์ด๋ฏธ ์ก์ ์๋ฌ๋ฅผ assertThat์ ํตํด ๋ ํ๋ฒ ๊ฒ์ฆํ๊ณ ์๋ค.
- ๋ฐํ๋ ์ค๋ฅ๋ฉ์์ง๊ฐ ์์ํ ๋ฉ์์ง์ ๋์ผํ ์ง ํ์ธํ์ฌ
- ๋ค๋ฅด๋ค๋ฉด ํ
์คํธ ์คํจ๋ก ์ฒ๋ฆฌ๋๋ค.
- catch๋ก ์ด๋ฏธ ์ก์ ์๋ฌ๋ฅผ assertThat์ ํตํด ๋ ํ๋ฒ ๊ฒ์ฆํ๊ณ ์๋ค.
- ์ฝ๋
Assertions.assertThrows(์์ ์์ธํด๋์ค, ์คํ์ฝ๋Lambda)
: try/catch ๋์ ๊ฐ๋จํ ์ฌ์ฉํ ์ ์๋ค.
- ์๋น์ค ๊ฐ์
๋ฉ์๋์์ ์ค๋ณต๋ ์ด๋ฆ์ด ๊ฐ์
์ ์๋ํ๋ฉด IllegalStateException๋ฅผ ๋ฐ์์ํจ๋ค.
- assertThrows๋ ์์๋ ์์ธ๊ฐ ๋ฐ์ํ๋ฉด TEST RESULT๊ฐ โ ํต๊ณผํ๋ค.
โป ์ด์ ๊ฐ์ด ์์ธ ์์ฒด๋ฅผ ๋ณ์๋ก ๋ง๋ค์ด ๊ฒ์ฆํ ์๋ ์๋ค.
service์ test์์ ์ฌ์ฉํ๋
repository๋ฅผ ํ๋๋ก ๋ฌถ๊ธฐ
- ์ค์ ์ฝ๋์ ํ
์คํธ ์ฝ๋์์ ๋์ผํ Repository๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํด ์ฝ๋๋ฅผ ๋ฐ๊ฟ๋ณด๊ฒ ์ต๋๋ค.
- ์ด์ ์ฝ๋
- ์์ ์ฝ๋
- ๋ค๋ฅธ ํด๋์ค ์๋น์ค ํธ์ถ ์, ๋ฆฌํฌ์งํ ๋ฆฌ ์์๋ฅผ ์ฌ์ฉํ๊ฒ๋ ํฉ๋๋ค.
private final MemberRepository memberRepository; public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; }
- ํ
์คํธํด๋์ค
public class MemberServiceTest { // 1. MemberService memberService; MemoryMemberRepository memberRepository; @BeforeEach public void BeforeEach() { memberRepository = new MemoryMemberRepository(); // 2. memberService = new MemberService(memberRepository); }
- ํ
์คํธ์์๋ ์ ์ญ ๋ณ์๋ก ์๋น์ค์ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ
- @BoforeEash ๋ฉ์๋ ์์ ์๋น์ค ์ธ์คํด์ค ๋ง๋ค ๋ (์ ์ญ๋ณ์ ๋ฆฌํฌ์งํ ๋ฆฌ)๋ฅผ ๋ด์ ๋ง๋ญ๋๋ค.
- ์ด๋ ๊ฒ ํ๋ฉด ์๋น์ค์ ํ ์คํธ๋ ๊ฐ์ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
- ํ
์คํธ์์๋ ์ ์ญ ๋ณ์๋ก ์๋น์ค์ ๋ฆฌํฌ์งํ ๋ฆฌ๋ฅผ ๋ง๋ค๊ณ
๐ ์ด๋ฌํ ๊ธฐ์ ์ DI (Dependency injection). ์์กด์ฑ ์ฃผ์ ์ด๋ผ๊ณ ํฉ๋๋ค.
↓ํ ์คํธ์ฝ๋ ์ ์ฒด์ฝ๋ (findMembers()์ findOne() ํจ์ ํ ์คํธ ์ฝ๋๋ ์ ๊ฐ ์์ฑํด ์ฌ๋ฆฝ๋๋ค.)
๋๋ณด๊ธฐ
package hello.hellospring.service;
import static org.assertj.core.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import hello.hellospring.domain.Member;
import hello.hellospring.repository.MemoryMemberRepository;
public class MemberServiceTest {
MemberService memberService;
MemoryMemberRepository memberRepository;
@BeforeEach
public void BeforeEach() {
memberRepository = new MemoryMemberRepository();
memberService = new MemberService(memberRepository);
}
@AfterEach
public void AfterEach() {
memberRepository.clearStore();
}
@Test
void ํ์๊ฐ์
() {
//given
Member member = new Member();
member.setName("pring");
//when
Long saveId = memberService.join(member);
//then
Member findMember = memberService.findOne(saveId).get();
assertThat(member.getName()).isEqualTo(findMember.getName());
}
@Test
public void ์ค๋ณต_ํ์_์์ธ() {
//given
Member member1 = new Member();
member1.setName("spring");
Member member2 = new Member();
member2.setName("spring");
//when : ์ผ๋ถ๋ฌ ์ค๋ณต๊ฐ์
์ ๋ฐ์์ํจ๋ค.
memberService.join(member1);
IllegalStateException e = assertThrows(IllegalStateException.class, () -> memberService.join(member2));
assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์ฌํ๋ ํ์์
๋๋ค.");
/*
try {
memberService.join(member2);
fail();
} catch (IllegalStateException e) {
assertThat(e.getMessage()).isEqualTo("์ด๋ฏธ ์กด์ฌํ๋ ํ์์
๋๋ค.12341234");
}
*/
//then
}
@Test
void findMembers() {
//given
Member member1 = new Member();
member1.setName("Spring1");
memberService.join(member1);
Member member2 = new Member();
member2.setName("Spring2");
memberService.join(member2);
List<Member> lst = new ArrayList<>(Arrays.asList(member1));
lst.addAll(Arrays.asList(member2));
//when
List<Member> result = memberService.findMembers();
//then
for (int i = 0; i < result.size(); i++) {
assertThat(result.get(i)).isEqualTo(lst.get(i));
}
}
@Test
void findOne() {
// given
Member member1 = new Member();
member1.setName("Spring1");
memberService.join(member1);
Member member2 = new Member();
member2.setName("Spring2");
memberService.join(member2);
//when then
memberService.findOne(member2.getId())
.ifPresent(m -> {
assertThat(m).isEqualTo(member2);
});
}
}
ํ ์คํธ ์ฝ๋๋ ์ฌ์ค ํ๊ธ๋ก ์ ์ด๋ ์๊ด์ด ์๋ค.๐ ๋น๋ ๋ ๋ ํ ์คํธ ์ฝ๋๋ ํฌํจ๋์ง ์๊ธฐ ๋๋ฌธ์ด๋ค.
โป ์ฐธ์กฐ : https://www.inflearn.com/roadmaps/373
๋ฐ์ํ
'๐ Spring > ๐ Spring Boot' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[SpringBoot]์คํ๋ง ๋น ๋ฑ๋ก:2.์๋ฐ์ฝ๋ (0) | 2025.01.06 |
---|---|
[SpringBoot]์คํ๋ง ๋น ๋ฑ๋ก:1.์ปดํฌ๋ํธ ์ค์บ๊ณผ ์๋ ์์กด๊ด๊ณ ์ค์ (0) | 2025.01.06 |
[SpringBoot][JUnit]ํ์๊ด๋ฆฌ-๋๋ฉ์ธ๊ณผ ๋ฆฌํฌ์งํ ๋ฆฌ ๊ทธ๋ฆฌ๊ณ ํ ์คํธ (0) | 2025.01.04 |
[SpringBoot]ํ์๊ด๋ฆฌ-๋น์ง๋์ค ์๊ตฌ์ฌํญ ์ ๋ฆฌ (0) | 2025.01.04 |
[SpringBoot]์น ๊ฐ๋ฐ ๊ธฐ์ด-API @ResponseBody (0) | 2025.01.04 |