[Spring Boot] ํšŒ์› ๊ด€๋ฆฌ ์˜ˆ์ œ - Backend

2021. 8. 6. 08:00ใ†Back-End ์ž‘์—…์‹ค/Spring Framework

728x90
๋ฐ˜์‘ํ˜•

์•ˆ๋…•ํ•˜์„ธ์š”? ์ฃผ๋‹ˆํ•˜๋ž‘ ์ž…๋‹ˆ๋‹ค.

์ฃผ๋‹ˆํ•˜๋ž‘์€ Spring Boot์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

์ธํ”„๋Ÿฐ์˜ ๊น€์˜ํ•œ๋‹˜์˜ ์Šคํ”„๋ง ์ž…๋ฌธ - ์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ, ์›น MVC, DB ์ ‘๊ทผ ๊ธฐ์ˆ ์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ํ”ผ๋“œ๋ฅผ ์ž‘์„ฑ ํ•ด ๋ณด๋„๋ก ํ•  ๊ฒƒ์ด์—์š”.

๋ฐ”๋กœ ์‹œ์ž‘ ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค!

 

 


 

๐Ÿ“‹ ๋ชฉ์ฐจ


01.[Spring Boot] thymeleaf์™€ Spring Boot
02.[Spring Boot] Spring Web ๊ฐœ๋ฐœ ๊ธฐ์ดˆ
03.[Spring Boot] ํšŒ์› ๊ด€๋ฆฌ ์˜ˆ์ œ - Backend
04.[Spring Boot] Service ๊ฐœ๋ฐœ ๋ฐ Test Case ์ž‘์„ฑ
05.[Spring Boot] Spring Bean๊ณผ ์˜์กด๊ด€๊ณ„
06.[Spring Boot] Java Code๋กœ ์ง์ ‘ Spring Bean ๋“ฑ๋ก
07.[Spring Boot] ๋“ฑ๋ก, ๋ชฉ๋ก ๋ณด๊ธฐ ๊ตฌํ˜„ํ•˜๊ธฐ
08.[Spring Boot] ๊ธฐ์กด ์ฝ”๋“œ ์† ์•ˆ๋Œ€๊ณ , ์„ค์ •์œผ๋กœ ๊ตฌํ˜„ Class ๋ณ€๊ฒฝ
09.[Spring Boot] ํ†ตํ•ฉ Test
10.[Spring Boot] JPA
11.[Spring Boot] Spring Data JPA
12.[Spring Boot] AOP

 

 


 

 

๐Ÿ“Œ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์—


์ฝ”๋“œ์— ๊ด€๋ จํ•œ ๋‚ด์šฉ์€ ์ฃผ๋‹ˆํ•˜๋ž‘์˜ Github์—์„œ ํ™•์ธ ํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค!

 

 

 

๐Ÿ“Œ Web Application


 

  • Controller : Web MVC Control Role
  • Service : Core Business Logic Implementation
  • Repository : DB Access, Domain Entity Save to DB and management
  • Domain : Business Domain Entiry (Ex: ํšŒ์›, ์ฃผ๋ฌธ, ์ฟ ํฐ ๋“ฑ๋“ฑ ์ฃผ๋กœ DB์— ์ €์žฅํ•˜๊ณ  ๊ด€๋ฆฌ)

 

 

DB๊ฐ€ ์•„์ง ์„ ์ •๋˜์ง€ ์•Š์•˜๋‹ค๋ฉด ์šฐ์„  Interface๋กœ ๊ตฌํ˜„ Class๋ฅผ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“œ๋Š” ๊ฒƒ๋„ ๋ฐฉ๋ฒ•์ธ ๊ฒƒ์ด์—์š”.

DB๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ดˆ๊ธฐ ๊ฐœ๋ฐœ ๋‹จ๊ณ„์—์„œ๋Š” ๊ตฌํ˜„์ฒด๋กœ ๊ฐ€๋ฒผ์šด Memory ๊ธฐ๋ฐ˜ Data Repository๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ต๋‹ˆ๋‹ค.

 

 

๐Ÿ“Œ Test Case


๊ฐœ๋ฐœํ•œ ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•ด์„œ Test ํ•  ๋•Œ Java์˜ Main Method๋ฅผ ํ†ตํ•ด ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, Web Application์˜ Controller๋ฅผ ํ†ตํ•ด ํ•ด๋‹น ๊ธฐ๋Šฅ์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—์š”.
ํ•˜์ง€๋งŒ, ์ด๋Ÿฐ ๋ฐฉ๋ฒ•์€ ์ค€๋น„ํ•˜๊ณ , ์‹คํ–‰ํ•˜๋Š”๋ฐ, ์˜ค๋ž˜ ๊ฑธ๋ฆฌ๊ณ , ๋ฐ˜๋ณต ์‹คํ–‰ํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๊ธฐ ๋•Œ๋ฌธ์— ์ž˜ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์ด์—์š”.

JAVA๋Š” JUnit์ด๋ผ๋Š” Framwork๋ฅผ ํ†ตํ•ด Test๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด ์คŒ์œผ๋กœ ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•ด์ฃผ์—ˆ์–ด์š”.

 

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import java.util.List;


class MemoryMemberRepositoryTest {

    MemoryMemberRepository repository = new MemoryMemberRepository();

    @Test
    public void save() {    // MemoryMemberRepository์˜ save ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  Test
        Member member = new Member();
        member.setName("spring");

        repository.save(member);

        Member result = repository.findById(member.getId()).get();

        // member์•ˆ์˜ ๊ฐ’๊ณผ result์•ˆ์˜ ๊ฐ’์ด ๊ฐ™์€์ง€ ๋น„๊ต
        //Assertions.assertEquals(member, result);  ์˜ˆ์ „ ๊ธฐ๋ฒ•

        Assertions.assertThat(member).isEqualTo(result);

        System.out.println("save TEST์˜ result ๊ฐ’์€ " + (member == result) + " ์ž…๋‹ˆ๋‹ค.");
    }// save() ๋

    @Test
    public void findByName() {
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);

        Member result = repository.findByName("spring1").get();

        System.out.println("findByName TEST์˜ result ๊ฐ’์€ " + (result == member1) + " ์ž…๋‹ˆ๋‹ค.");

        Assertions.assertThat(result).isEqualTo(member1);
    } // findByName() ๋

    @Test
    public void findAll() {
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);

        List<Member> result = repository.findAll();

        System.out.println("findByALL TEST์˜ result ํฌ๊ธฐ๋Š” " + result.size() + " ์ž…๋‹ˆ๋‹ค.");

        Assertions.assertThat(result.size()).isEqualTo(2);
    } // findAll() ๋
}// TEST Class () ๋

 

์ด๋ ‡๊ฒŒ ํ•ด์„œ ๊ฐ๊ฐ์˜ Test๋ฅผ ๋Œ๋ฆฌ๋ฉด ์ •์ƒ์ ์œผ๋กœ ๋™์ž‘์ด ๋˜๋Š” ๊ฒƒ์ด์—์š”.

ํ•˜์ง€๋งŒ, ์ „์ฒด ํ…Œ์ŠคํŠธ๋ฅผ ๋™์ž‘ ์‹œํ‚ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ Error๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๊ฒƒ์ด์—์š”.

<findByName Test ํ•˜๋‚˜๋ฅผ ์‹คํ–‰ํ–ˆ์„ ๊ฒฝ์šฐ ์ •์ƒ>

 

<์ „์ฒด๋ฅผ ์‹คํ–‰ ์‹œ์ผฐ์„ ๊ฒฝ์šฐ Error>

 

์œ„์™€ ๊ฐ™์ด Error๊ฐ€ ๋‚˜๋Š” ์ด์œ ๋Š” ์ฝ”๋“œ์—์„œ ๋ดค์„ ๋• findAll() ์ด ๋งจ ์•„๋ž˜์ง€๋งŒ, Test๋ฅผ ํ•  ๋•Œ ๋ณด๋ฉด ๋งจ ์œ„์— ์‹คํ–‰ ๋œ ๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

์ฆ‰, Test๋Š” ์ˆœ์„œ์™€ ๊ด€๊ณ„ ์—†์ด ์‹คํ–‰์ด ๋˜๋ฉฐ, ์ด๋ ‡๊ฒŒ Error๊ฐ€ ๋‚˜๋Š” ์ด์œ ๋Š” findAll()์—์„œ Member Entity๋ฅผ member1์œผ๋กœ ๋งŒ๋“  ๋’ค ์—ฌ๊ธฐ์„œ "spring1"์„ ๋„ฃ๊ณ , 2์— "spring2"๋ฅผ ๋„ฃ์—ˆ๋Š”๋ฐ, findByName()์—์„œ๋„ ๋™์ผํ•œ ์ž‘์—…์„ ํ•ด์ฃผ๊ณ  ์žˆ๋Š” ๊ฒƒ์ด์—์š”.

์ด๋ฏธ findAll์—์„œ ํ•ด๋‹น ๋‚ด์šฉ์œผ๋กœ Memory๊ฐ€ ์‚ฌ์šฉ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ฎ์–ด์“ฐ๊ธฐ๊ฐ€ ๋˜์ง€ ์•Š์•„ ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ์ธ ๊ฒƒ์ด์—์š”.

 

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด Test Code์— @AfterEach๋ฅผ ๋„ฃ์–ด์ค€ ๊ฒƒ์ด์—์š”.

package hello.hellospring.repository;

import hello.hellospring.domain.Member;
import org.assertj.core.api.Assertions;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import java.util.List;


class MemoryMemberRepositoryTest {

    MemoryMemberRepository repository = new MemoryMemberRepository();

    @AfterEach
    // Test๊ฐ€ ํ•˜๋‚˜ ๋๋‚  ๋•Œ๋งˆ๋‹ค Repository๋ฅผ Clear ์‹œ์ผœ์ฃผ๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ
    public void afterEach() {
        repository.clearStore();
    }

    @Test
    public void save() {    // MemoryMemberRepository์˜ save ๋ฉ”์†Œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ  Test
        Member member = new Member();
        member.setName("spring");

        repository.save(member);

        Member result = repository.findById(member.getId()).get();

        // member์•ˆ์˜ ๊ฐ’๊ณผ result์•ˆ์˜ ๊ฐ’์ด ๊ฐ™์€์ง€ ๋น„๊ต
        //Assertions.assertEquals(member, result);  ์˜ˆ์ „ ๊ธฐ๋ฒ•

        Assertions.assertThat(member).isEqualTo(result);

        System.out.println("save TEST์˜ result ๊ฐ’์€ " + (member == result) + " ์ž…๋‹ˆ๋‹ค.");
    }// save() ๋

    @Test
    public void findByName() {
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);

        Member result = repository.findByName("spring1").get();

        System.out.println("findByName TEST์˜ result ๊ฐ’์€ " + (result == member1) + " ์ž…๋‹ˆ๋‹ค.");

        Assertions.assertThat(result).isEqualTo(member1);
    } // findByName() ๋

    @Test
    public void findAll() {
        Member member1 = new Member();
        member1.setName("spring1");
        repository.save(member1);

        Member member2 = new Member();
        member2.setName("spring2");
        repository.save(member2);

        List<Member> result = repository.findAll();

        System.out.println("findByALL TEST์˜ result ํฌ๊ธฐ๋Š” " + result.size() + " ์ž…๋‹ˆ๋‹ค.");

        Assertions.assertThat(result.size()).isEqualTo(2);
    } // findAll() ๋
}// TEST Class () ๋

@AfterEach๋Š” ๊ฐ Test๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ ๋งˆ๋‹ค ์ด ๊ธฐ๋Šฅ์„ ์‹คํ–‰ ํ•ด ์ฃผ๋Š”๋ฐ, ์—ฌ๊ธฐ์—์„œ๋Š” Memory DB์— ์ €์žฅ๋œ Data๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์ด์—์š”.

 

MemoryMemberRepository.java

package hello.hellospring.repository;


import hello.hellospring.domain.Member;

import java.util.*;

public class MemoryMemberRepository implements MemeberRepository{

    private static Map<Long, Member> store = new HashMap<>();
    private static long sequence = 0L;

    @Override
    public Member save(Member member) {
        member.setId(++sequence);
        store.put(member.getId(), member);
        return member;
    } //save () ๋

    @Override
    public Optional<Member> findById(Long id) {
        return Optional.ofNullable(store.get(id));
    } // findById() ๋

    @Override
    public Optional<Member> findByName(String name) {
       return store.values().stream().filter(member -> member.getName().equals(name)).findAny();
    } // findByName () ๋

    @Override
    public List<Member> findAll() {
        return new ArrayList<>(store.values());
    } // findAll() ๋

    // Test๊ฐ€ ํ•˜๋‚˜ ๋๋‚  ๋•Œ๋งˆ๋‹ค Repository๋ฅผ Clear ์‹œ์ผœ์ฃผ๊ธฐ ์œ„ํ•œ ์ฝ”๋“œ (MemoryMemberRepositoryTest์˜ afterEach()์—์„œ ํ˜ธ์ถœ)
    public void clearStore() {
        store.clear();
    }
} // Class ๋

 

 

๐Ÿ’ก ์ฐธ๊ณ 
Test๋Š” ๊ฐ๊ฐ ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜์–ด์•ผ ํ•˜๋ฉฐ, ํ…Œ์ŠคํŠธ ์ˆœ์„œ์— ์˜์กด๊ด€๊ณ„๊ฐ€ ์žˆ๋Š” ๊ฒƒ์€ ์ข‹์ง€ ์•Š์€ Test

 

 

 


 

์ฃผ๋‹ˆํ•˜๋ž‘์˜ ๊ธ€์ด ๋งˆ์Œ์— ๋“œ์…จ๋‚˜์š”? ๊ตฌ๋…๊ณผ ๊ณต๊ฐ! ๊ทธ๋ฆฌ๊ณ , ๋Œ“๊ธ€์€ ์ฃผ๋‹ˆํ•˜๋ž‘์—๊ฒŒ ๋งŽ์€ ํž˜์ด ๋ฉ๋‹ˆ๋‹ค

728x90
๋ฐ˜์‘ํ˜•