0606 ~ 0619


# 0606 ~ 0619

# 0610 - ํ…Œ์ŠคํŠธ ๋”๋ธ” (Test Double)

# ํ…Œ์ŠคํŠธ ๋”๋ธ”(Test Double)์ด๋ž€?

xUnit Test Patterns์˜ ์ €์ž์ธ ์ œ๋ผ๋“œ ๋ฉ”์Šค์ž๋กœ์Šค๊ฐ€ ๋งŒ๋“  ์šฉ์–ด๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ฒฝ์šฐ ์ด๋ฅผ ๋Œ€์‹ ํ•ด ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ฐ์ฒด๋ฅผ ๋งํ•œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด ์šฐ๋ฆฌ๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ๋ถ€ํ„ฐ ์กฐํšŒํ•œ ๊ฐ’์„ ์—ฐ์‚ฐํ•˜๋Š” ๋กœ์ง์„ ๊ตฌํ˜„ํ–ˆ๋‹ค๊ณ  ํ•˜์ž. ํ•ด๋‹น ๋กœ์ง์„ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด์„  ํ•ญ์ƒ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์˜ํ–ฅ์„ ๋ฐ›์„ ๊ฒƒ์ด๊ณ , ์ด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์ƒํƒœ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ๊ฒฐ๊ณผ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ด๋ ‡๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๋ ค๋Š” ๊ฐ์ฒด์™€ ์—ฐ๊ด€๋œ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๊ณ  ๋ชจํ˜ธํ•  ๋•Œ ๋Œ€์‹  ํ•ด์ค„ ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ํ…Œ์ŠคํŠธ ๋”๋ธ”์ด๋ผ ํ•œ๋‹ค.

# ํ…Œ์ŠคํŠธ ๋”๋ธ”์˜ ์ข…๋ฅ˜

ํ…Œ์ŠคํŠธ ๋”๋ธ”์€ ํฌ๊ฒŒ Dummy, Fake, Stub, Spy, Mock์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

# 1. Dummy

  • ๊ฐ€์žฅ ๊ธฐ๋ณธ์ ์ธ ํ…Œ์ŠคํŠธ ๋”๋ธ”์ด๋‹ค.
  • ์ธ์Šคํ„ด์Šคํ™” ๋œ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ๊ธฐ๋Šฅ์€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค.
  • Dummy ๊ฐ์ฒด์˜ ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ ์ •์ƒ ๋™์ž‘์€ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๊ฐ์ฒด๋Š” ์ „๋‹ฌ๋˜์ง€๋งŒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด์ด๋‹ค.

์ •๋ฆฌํ•˜๋ฉด ์ธ์Šคํ„ด์Šคํ™”๋œ ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•ด์„œ ๊ตฌํ˜„ํ•œ ๊ฐ€์งœ ๊ฐ์ฒด์ผ ๋ฟ์ด๊ณ , ์ƒ์„ฑ๋œ Dummy ๊ฐ์ฒด๋Š” ์ •์ƒ์ ์ธ ๋™์ž‘์„ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

public interface PringWarning {
    void print();
}
public class PrintWarningDummy implements PrintWarning {
    @Override
    public void print() {
        // ์•„๋ฌด๋Ÿฐ ๋™์ž‘์„ ํ•˜์ง€ ์•Š๋Š”๋‹ค.
    }
}

์‹ค์ œ ๊ฐ์ฒด๋Š” PrintWarning ์ธํ„ฐํŽ˜์ด์Šค์˜ ๊ตฌํ˜„์ฒด๋ฅผ ํ•„์š”ํ•˜์ง€๋งŒ, ํŠน์ • ํ…Œ์ŠคํŠธ์—์„œ๋Š” ํ•ด๋‹น ๊ตฌํ˜„์ฒด์˜ ๋™์ž‘์ด ์ „ํ˜€ ํ•„์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค. ์‹ค์ œ ๊ฐ์ฒด๊ฐ€ ๋กœ๊ทธ์šฉ ๊ฒฝ๊ณ ๋งŒ ์ถœ๋ ฅํ•œ๋‹ค๋ฉด ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ๋Š” ์ „ํ˜€ ํ•„์š” ์—†๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์ด๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” print()๊ฐ€ ์•„๋ฌด๋Ÿฐ ๋™์ž‘์„ ํ•˜์ง€ ์•Š์•„๋„ ํ…Œ์ŠคํŠธ์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š”๋‹ค.
์ด์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜์ง€ ์•Š์•„๋„ ํ…Œ์ŠคํŠธ์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋ฅผ Dummy ๊ฐ์ฒด๋ผ๊ณ  ํ•œ๋‹ค.

# 2. Fake

  • ๋ณต์žกํ•œ ๋กœ์ง์ด๋‚˜ ๊ฐ์ฒด ๋‚ด๋ถ€์—์„œ ํ•„์š”๋กœ ํ•˜๋Š” ๋‹ค๋ฅธ ์™ธ๋ถ€ ๊ฐ์ฒด๋“ค์˜ ๋™์ž‘์„ ๋‹จ์ˆœํ™”ํ•˜์—ฌ ๊ตฌํ˜„ํ•œ ๊ฐ์ฒด์ด๋‹ค.
  • ๋™์ž‘์˜ ๊ตฌํ˜„์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€๋งŒ ์‹ค์ œ ํ”„๋กœ๋•์…˜์—๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์€ ๊ฐ์ฒด์ด๋‹ค.

์ •๋ฆฌํ•˜๋ฉด ๋™์ž‘์€ ํ•˜์ง€๋งŒ ์‹ค์ œ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ์ฒด์ฒ˜๋Ÿผ ์ •๊ตํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€๋Š” ์•Š๋Š” ๊ฐ์ฒด๋ฅผ ๋งํ•œ๋‹ค.

@Entity
public class User {
    @Id
    private Long id;
    private String name;
    
    protected User() {}
    
    public User(Long id, String name) {
        this.id = id;
        this.name = name;
    }
    
    public Long getId() {
        return this.id;
    }
    
    public String getName() {
        return this.name;
    }
}
public interface UserRepository {
    void save(User user);
    User findById(long id);
}
public class FakeUserRepository implements UserRepository {
    private Collection<User> users = new ArrayList<>();
    
    @Override
    public void save(User user) {
        if (findById(user.getId()) == null) {
            user.add(user);
        }
    }
    
    @Override
    public User findById(long id) {
        for (User user : users) {
            if (user.getId() == id) {
                return user;
            }
        }
        return null;
    }
}

ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๊ด€๋˜์–ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•œ๋‹ค.

๊ทธ๋Ÿด ๊ฒฝ์šฐ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์—ฐ๊ฒฐํ•ด์„œ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ•˜์ง€๋งŒ, ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋Œ€์‹  ๊ฐ€์งœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—ญํ• ์„ ํ•˜๋Š” FakeUserRepository๋ฅผ ๋งŒ๋“ค์–ด ํ…Œ์ŠคํŠธ๊ฐ์ฒด์— ์ฃผ์ž…ํ•˜๋Š” ๋ฐฉ๋ฒ•๋„ ์žˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ…Œ์ŠคํŠธ ๊ฐ์ฒด๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์˜์กดํ•˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘์„ํ•˜๋Š” ๊ฐ€์งœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ฐ€์ง€๊ฒŒ ๋œ๋‹ค.

# 3. Stub

  • Dummy ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ๋กœ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋งŒ๋“ค์–ด ๋†“์€ ๊ฐ์ฒด์ด๋‹ค.
  • ์ธํ„ฐํŽ˜์ด์Šค ๋˜๋Š” ๊ธฐ๋ณธ ํด๋ž˜์Šค๊ฐ€ ์ตœ์†Œํ•œ์œผ๋กœ ๊ตฌํ˜„๋œ ์ƒํƒœ์ด๋‹ค.
  • ํ…Œ์ŠคํŠธ์—์„œ ํ˜ธ์ถœ๋œ ์š”์ฒญ์— ๋Œ€ํ•ด ๋ฏธ๋ฆฌ ์ค€๋น„ํ•ด๋‘” ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

์ •๋ฆฌํ•˜๋ฉด ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ํ”„๋กœ๊ทธ๋ž˜๋ฐ๋œ ๋‚ด์šฉ์— ๋Œ€ํ•ด์„œ๋งŒ ์ค€๋น„๋œ ๊ฒฐ๊ณผ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ฐ์ฒด์ด๋‹ค.

public class StubUserRepository implements UserRepository {
    // ...
    @Override
    public User findById(long id) {
        return new User(id, "Test User");
    }
}

์œ„์˜ ์ฝ”๋“œ์ฒ˜๋Ÿผ StubUserRepository๋Š” findByID() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์–ธ์ œ๋‚˜ ๋™์ผํ•œ id๊ฐ’์— TestUser๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ User ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜๋ฐ›๋Š”๋‹ค.
ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ User ์ธ์Šคํ„ด์Šค์˜ name์„ Test User๋งŒ ๋ฐ›๊ธฐ๋ฅผ ์›ํ•˜๋Š” ๊ฒฝ์šฐ ์ด์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
๋ฌผ๋ก  ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์˜ ๋‹จ์ ์€ ํ…Œ์ŠคํŠธ๊ฐ€ ์ˆ˜์ •๋  ๊ฒฝ์šฐ Stub ๊ฐ์ฒด๋„ ํ•จ๊ป˜ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ํ…Œ์ŠคํŠธ์—์„œ ์ž์ฃผ ์‚ฌ์šฉํ•˜๋Š” Mockito ํ”„๋ ˆ์ž„์›Œํฌ๋„ Stub์™€ ๊ฐ™์€ ์—ญํ• ์„ ํ•ด์ค€๋‹ค.
์ด์ฒ˜๋Ÿผ ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด ์˜๋„ํ•œ ๊ฒฐ๊ณผ๋งŒ ๋ฐ˜ํ™˜๋˜๋„๋ก ํ•˜๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด๊ฐ€ Stub์ด๋‹ค.

# 4. Spy

  • Stub์˜ ์—ญํ• ์„ ๊ฐ€์ง€๋ฉด์„œ ํ˜ธ์ถœ๋œ ๋‚ด์šฉ์— ๋Œ€ํ•ด ์•ฝ๊ฐ„์˜ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.
  • ํ…Œ์ŠคํŠธ ๋”๋ธ”๋กœ ๊ตฌํ˜„๋œ ๊ฐ์ฒด์— ์ž๊ธฐ ์ž์‹ ์ด ํ˜ธ์ถœ ๋˜์—ˆ์„ ๋•Œ ํ™•์ธ์ด ํ•„์š”ํ•œ ๋ถ€๋ถ„์„ ๊ธฐ๋กํ•˜๋„๋ก ๊ตฌํ˜„ํ•œ๋‹ค.
  • ์‹ค์ฒด ๊ฐ์ฒด์ฒ˜๋Ÿผ ๋™์ž‘์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ๊ณ , ํ•„์š”ํ•œ ๋ถ€๋ถ„์— ๋Œ€ํ•ด์„œ๋Š” Stub๋กœ ๋งŒ๋“ค์–ด์„œ ๋™์ž‘์„ ์ง€์ •ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ •๋ฆฌํ•˜๋ฉด ์‹ค์ œ ๊ฐ์ฒด๋กœ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  Stub ๊ฐ์ฒด๋กœ๋„ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ํ•„์š”ํ•œ๊ฒฝ์šฐ ํŠน์ • ๋ฉ”์„œ๋“œ๊ฐ€ ์ œ๋Œ€๋กœ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

public class MailingService {
    private int sendMailCount = 0;
    private Collection<Mail> mails = new ArrayList<>();

    public void sendMail(Mail mail) {
        sendMailCount++;
        mails.add(mail);
    }

    public long getSendMailCount() {
        return sendMailCount;
    }
}

MailingService๋Š” sendMail์„ ํ˜ธ์ถœํ•  ๋•Œ๋งˆ๋‹ค ๋ณด๋‚ธ ๋ฉ”์ผ์„ ์ €์žฅํ•˜๊ณ  ๋ช‡ ๋ฒˆ ๋ณด๋ƒˆ๋Š”์ง€๋ฅผ ์ฒดํฌํ•œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚˜์ค‘์— ๋ฉ”์ผ์„ ๋ณด๋‚ธ ํšŸ์ˆ˜๋ฅผ ๋ฌผ์–ด๋ณผ ๋•Œ sendMailCount๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
์ด์ฒ˜๋Ÿผ ์ž๊ธฐ ์ž์‹ ์ด ํ˜ธ์ถœ๋œ ์ƒํ™ฉ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ Spy์ด๋‹ค.
์ด ๋˜ํ•œ Mockito ํ”„๋ ˆ์ž„์›Œํฌ์˜ verify() ๋ฉ”์„œ๋“œ๊ฐ€ ๊ฐ™์€ ์—ญํ• ์„ ํ•œ๋‹ค.

# 5. Mock

  • ํ˜ธ์ถœ์— ๋Œ€ํ•œ ๊ธฐ๋Œ€๋ฅผ ๋ช…์„ธํ•˜๊ณ  ๋‚ด์šฉ์— ๋”ฐ๋ผ ๋™์ž‘ํ•˜๋„๋ก ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋œ ๊ฐ์ฒด.
  • Mockito ํ”„๋ ˆ์ž„์›Œํฌ๊ฐ€ ๋Œ€ํ‘œ์ ์ธ Mock ํ”„๋ ˆ์ž„์›Œํฌ.
@ExtendWith(MockitoExtension.class)
public class UserServiceTest {
    @Mock
    private UserRepository userRepository;
    
    @Test
    void test() {
        when(userRepository.findById(anyLong())).thenReturn(new User(1, "Test User"));
        
        User actual = userService.findById(1);
        assertThat(actual.getId()).isEqualTo(1);
        assertThat(actual.getName()).isEqualTo("Test User");
    }
}

# 0613 - orphanRemoval

๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ์™€ ์—ฐ๊ด€๊ด€๊ณ„๊ฐ€ ๋Š์–ด์ง„ ์ž์‹ ์—”ํ‹ฐํ‹ฐ๋ฅผ ์ž๋™์œผ๋กœ ์‚ญ์ œํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ์ด๋‹ค.

@Entity
public class Parent {

    @Id
    @GeneratedValue
    private Long id;

    private String username;

    @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Child> childList = new ArrayList<>();
}

orphanRemoval๊ฐ€ true ์‹œ

Parent parent1 = em.find(Parent.class, parent.getId());
parent1.getChildList().remove(0); // delete ์ฟผ๋ฆฌ๋‚˜๊ฐ„๋‹ค.

์ž๋™์œผ๋กœ delete ์ฟผ๋ฆฌ๊ฐ€ ๋‚˜๊ฐ„๋‹ค.

  • ์ด ์†์„ฑ์€ ์ฐธ์กฐํ•˜๋Š” ๊ณณ์ด ํ•˜๋‚˜์ผ ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • ํŠน์ • ์—”ํ‹ฐํ‹ฐ๊ฐ€ ๊ฐœ์ธ ์†Œ์œ ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.
  • @OneToOne๊ณผ @OneToMany์—์„œ๋งŒ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

CascadeType.ALL + orphanRemovel=true
์ด ๋‘๊ฐœ๋ฅผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜๋ฉด ๋ถ€๋ชจ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ž์‹์˜ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๋ชจ๋‘ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.


# 0615 - CQRS

# CQRS ์•„ํ‚คํ…์ฒ˜๋ž€?

image

๋ช…๋ น(์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ) ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ์™€ ์ฟผ๋ฆฌ(์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ ์กฐํšŒ) ์—ญํ• ์„ ๊ตฌ์ƒˆํ•ญํ•˜๋Š” ๊ตฌ์„ฑ ์š”์†Œ๋ฅผ ๋‚˜๋ˆ„๋Š” ์•„ํ‚คํ…์ฒ˜

์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ์ฝ”๋“œ์™€ ์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ๋”ฐ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ, ๊ตฌํ˜„๋ฐฉ์‹์ด๋‚˜ ์‹œ์Šคํ…œ ๊ทœ๋ชจ์— ๋”ฐ๋ผ์„œ DB๋ฅผ ๋‚˜๋ˆ„๊ธฐ๋„ํ•˜๊ณ  ํ”„๋กœ์„ธ์Šค๋ฅผ ๋‚˜๋ˆ„๊ธฐ๋„ ํ•จ

  • Command : ๋ช…๋ น
    • ์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ
    • ex) ์ฃผ๋ฌธ ์ƒ์„ฑ, ์ˆ˜์ •, ์ทจ์†Œ
  • Query : ์กฐํšŒ
    • ์‹œ์Šคํ…œ ๋ฐ์ดํ„ฐ ์กฐํšŒ
    • ex) ์ฃผ๋ฌธ ์กฐํšŒ
  • Responsibility : ์ฑ…์ž„
    • ๊ตฌ์„ฑ ์š”์†Œ์˜ ์—ญํ• 
    • ๊ตฌ์„ฑ ์š”์†Œ ex) ํด๋ž˜์Šค, ํ•จ์ˆ˜, ๋ชจ๋“ˆ, ํŒจํ‚ค์ง€, ์›น์„œ๋ฒ„, DB ๋“ฑ
  • Segregation : ์—ญํ• ์— ๋”ฐ๋ผ ๊ตฌ์„ฑ ์š”์†Œ ๋‚˜๋ˆ„๊ธฐ

# ๋‹จ์ผ ๋ชจ๋ธ์˜ ๋‹จ์ 

๋ช…๋ น๊ณผ ์ฟผ๋ฆฌ๋ฅผ ๊ตฌ๋ถ„ํ•ด ํ”ผํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋“ค

image

  • ๊ธฐ๋Šฅ ์ถ”๊ฐ€์— ๋”ฐ๋ผ ์ฝ”๋“œ์˜ ์ฑ…์ž„์ด ๋ชจํ˜ธํ•ด์ง€๊ณ , ๊ธฐ๋Šฅ๋งˆ๋‹ค ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์— ์˜์กดํ•˜๊ฒŒ ๋œ๋‹ค
  • ๋ช…๋ น์€ ํ•œ ์˜์—ญ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃจ๋Š”๋ฐ ๋ฐ˜ํ•ด ์ฟผ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ์˜์—ญ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ช…๋ น๊ณผ ์ฟผ๋ฆฌ๋Š” ์ฝ”๋“œ ๋ณ€๊ฒฝ ๋นˆ๋„์™€ ์‚ฌ์šฉ์ž๊ฐ€ ๋‹ค๋ฅด๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ ์ด์œ ๋กœ ๋ชจ๋ธ์˜ ์ฝ”๋“œ๊ฐ€ ๋ฐ”๋€๋‹ค๋Š” ๊ฒƒ์€ ์ฑ…์ž„์˜ ๋ถ„๋ฆฌ๊ฐ€ ์ ์ ˆํ•˜์ง€ ์•Š๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
  • ๊ธฐ๋Šฅ๋งˆ๋‹ค ์š”๊ตฌ ์„ฑ๋Šฅ์ด ๋‹ค๋ฅด๋‹ค. ๋‹จ์ผ ๋ชจ๋ธ์€ ๊ธฐ๋Šฅ์— ๋งž๋Š” ๋‹ค์–‘ํ•œ ์„ฑ๋Šฅ ํ–ฅ์ƒ ๊ธฐ๋ฒ• ์ ์šฉ์ด ์–ด๋ ต๋‹ค.
    • ex) ๋ช…๋ น : ์‚ฌ์šฉ์ž ์ฃผ๋ฌธ ๊ธฐ๋Šฅ, ์ฟผ๋ฆฌ : ๋ฐฑ์˜คํ”ผ์Šค ์ฃผ๋ฌธ ๋ชฉ๋ก ์กฐํšŒ

# CQRS์˜ ๊ตฌํ˜„

# ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค, ๊ฐ™์€ DBMS

image

  • ์ฝ”๋“œ ์ˆ˜์ค€์—์„œ๋งŒ ๋ช…๋ น๊ณผ ์ฟผ๋ฆฌ๊ฐ€ ๋ถ„๋ฆฌ๋œ๋‹ค
  • ๋ฐ์ดํ„ฐ์˜ ๋™์ผ์„ฑ์ด ๋ณด์žฅ๋œ๋‹ค

# ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค, ๊ฐ™์€ DBMS, ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”

Image

  • ์ฟผ๋ฆฌ ์ „์šฉ ํ…Œ์ด๋ธ”์„ ์‚ฌ์šฉํ•œ๋‹ค
  • ์ฝ”๋“œ ์ˆ˜์ค€, ๋ฐ์ดํ„ฐ ์ˆ˜์ค€์—์„œ ๋ช…๋ น๊ณผ ์ฟผ๋ฆฌ๊ฐ€ ๋ถ„๋ฆฌ๋œ๋‹ค
  • ๋ช…๋ น์ด ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ• ๋•Œ, ์ฟผ๋ฆฌ ์ „์šฉ ํ…Œ์ด๋ธ”๋„ ์ˆ˜์ •ํ•ด์•ผํ•œ๋‹ค

# ๊ฐ™์€ ํ”„๋กœ์„ธ์Šค, ๋‹ค๋ฅธ DBMS

image

  • Redis๋ฅผ ์บ์‹œ๋กœ ํ•˜๊ณ  ์ฟผ๋ฆฌ DB๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค

# ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค, ๋‹ค๋ฅธ DBMS

![image]

  • MSA๋ฅผ ์ƒ๊ฐํ•ด๋ณผ ์ˆ˜ ์žˆ๋‹ค

# 3๊ฐ€์ง€ ๋ณ€๊ฒฝ ์ „ํŒŒ ์ „๋žต

CQRS ์•„ํ‚คํ…์ฒ˜์—์„œ ์—ฌ๋Ÿฌ DBMS๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋œ๋‹ค๋ฉด ๋ณ€๊ฒฝ ์ „ํŒŒ ์ „๋žต๋„ ์ˆ˜๋ฆฝํ•ด์•ผ ํ•œ๋‹ค

# ๋ช…๋ น์ด ์ฟผ๋ฆฌ DBMS๋ฅผ ์ˆ˜์ •

  • ๊ตฌํ˜„์ด ๋‹จ์ˆœ
  • ์ฟผ๋ฆฌ DB ์žฅ์• ์‹œ ๋ฐ์ดํ„ฐ ์œ ์‹ค ๊ฐ€๋Šฅ์„ฑ์ด ์žˆ๋‹ค
  • ๋ช…๋ น ๊ธฐ๋Šฅ์ด ์ฟผ๋ฆฌ DB๊นŒ์ง€ ์ ‘๊ทผํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ช…๋ น ๊ธฐ๋Šฅ์˜ ์—๋Ÿฌ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค

# ๋ณ€๊ฒฝ ๋‚ด์šฉ ๊ธฐ๋ก ํ›„, ์ „ํŒŒ๊ธฐ ์‚ฌ์šฉ

  • ๋ช…๋ น DB์— ๋ณ€๊ฒฝ ๋‚ด์šฉ ํ…Œ์ด๋ธ”์„ ๊ด€๋ฆฌํ•ด์•ผํ•œ๋‹ค
  • ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ๊ณผ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ํ•˜๋‚˜์˜ ํŠธ๋žœ์žญ์…˜์œผ๋กœ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด ๋ฐ์ดํ„ฐ ์œ ์‹ค ๋ฐฉ์ง€๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค
  • ์ „ํŒŒ๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•ด์•ผํ•œ๋‹ค

# DB๊ฐ€ ์ œ๊ณตํ•˜๋Š” CDC ์‚ฌ์šฉ

  • CDC : ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์žˆ๋Š” ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์„ ํŒŒ์•…ํ•˜๊ณ  ์ถ”์ ํ•˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด ํ”„๋กœ์„ธ์Šค
  • ๋ช…๋ น DB ๋ฐ”์ด๋„ˆ๋ฆฌ ๋กœ๊ทธ๋ฅผ ์ฝ์–ด ๋ณ€๊ฒฝ์„ ํŒŒ์•…ํ•˜๊ณ , ์ฟผ๋ฆฌ DB์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋ช…๋ น ์ฝ”๋“œ๊ฐ€ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ๊ด€๋ฆฌํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค

# 0616 - MSA์™€ SOA์˜ ์ฐจ์ด

# SOA, MSA๋ž€?

SOA๋Š” ์„œ๋น„์Šค ์ง€ํ–ฅ ์„ค๊ณ„ ๋ฐฉ์‹(Service Oriented Architecture)
SOA๋Š” ์„œ๋น„์Šค ๋‹จ์œ„๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๊ณ , ๊ฐœ๋ฐœ๋œ ์„œ๋น„์Šค๋“ค์„ ๊ณต์œ ํ•จ์œผ๋กœ์จ ์žฌ๊ฐ€์šฉ์„ฑ์„ ๋Š˜๋ฆฌ๊ณ  ์œ ์—ฐ์„ฑ์„ ํ™•๋ณดํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ

MSA๋Š” ๋งˆ์ดํฌ๋กœ ์„œ๋น„์Šค ์„ค๊ณ„ ๋ฐฉ์‹(Micro Service Architecture)
MSA ๋˜ํ•œ ์•„์ฃผ ์ž‘์€ ๋‹จ์œ„์˜ ์„œ๋น„์Šค๋กœ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ๊ตฌ์„ฑํ•จ์œผ๋กœ์จ ๋ฏผ์ฒฉํ•˜๊ณ  ์œ ์—ฐํ•œ ์„ค๊ณ„ํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ

# ๊ณต์œ  ์ง€ํ–ฅ์ 

image

SOA๋Š” ๋น„์ง€๋‹ˆ์Šค ์ธก๋ฉด์—์„œ์˜ ์„œ๋น„์Šค ์žฌ์‚ฌ์šฉ์„ฑ์„ ์ค‘์š”์‹œํ•˜์—ฌ ESB(Enterprise Service Bus)๋ผ๋Š” ์„œ๋น„์Šค ์ฑ„๋„ ์ด์šฉ -> ์„œ๋น„์Šค ๊ณต์œ , ์žฌ์‚ฌ์šฉ

MSA๋Š” ํ•œ ๊ฐ€์ง€ ์ž‘์€ ์„œ๋น„์Šค์— ์ง‘์ค‘ํ•˜์—ฌ ์„œ๋น„์Šค ๊ณต์œ ํ•˜์ง€ ์•Š๊ณ  ๋…๋ฆฝ์  ์‹คํ–‰

  • SOA : ์žฌ์‚ฌ์šฉ์„ ํ†ตํ•œ ๋น„์šฉ ์ ˆ๊ฐ
  • MSA : ์„œ๋น„์Šค ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถ”์–ด ๋ณ€ํ™”์— ๋Šฅ๋™์ ์œผ๋กœ ๋Œ€์‘

# ๊ธฐ์ˆ  ๋ฐฉ์‹

  • SOA๋Š” ๊ณตํ†ต์˜ ์„œ๋น„์Šค๋ฅผ esb์— ๋ชจ์•„ ์‚ฌ์—… ์ธก๋ฉด์—์„œ ๊ณตํ†ต ์„œ๋น„์Šค ํ˜•์‹์œผ๋กœ ์„œ๋น„์Šค ์ œ๊ณต
  • MSA๋Š” ๊ฐ ๋…๋ฆฝ๋œ ์„œ๋น„์Šค๊ฐ€ ๋…ธ์ถœ๋œ REST API๋ฅผ ์‚ฌ์šฉ
  • SOA๋Š” ์„œ๋น„์Šค๋ฅผ ๊ฐœ๋ฐœํ•˜๊ณ  ์ตœ๋Œ€ํ•œ ์žฌ๊ฐ€์šฉ
  • MSA๋Š” ์„œ๋น„์Šค๊ฐ€ ๊ณต์œ ๋˜๊ธฐ ๋ณด๋‹ค ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ์ง€ํ–ฅ

# 0618 - ์ž๋ฐ” ํ…Œ์ŠคํŠธ ๊ฒฉ๋ฆฌ

# ํ…Œ์ŠคํŠธ ๊ฒฉ๋ฆฌ๋ž€?

ํ…Œ์ŠคํŠธ๋Š” ์ˆœ์„œ์— ์ƒ๊ด€์—†์ด ๋…๋ฆฝ์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉฐ ๊ฒฐ์ •์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค. ํ…Œ์ŠคํŠธ๋ฅผ ์„œ๋กœ ๊ฒฉ๋ฆฌํ•˜์—ฌ ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ๋„ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ํ•ด์•ผํ•œ๋‹ค.

# ๊ณ„์ธต๋ณ„ ํ…Œ์ŠคํŠธ

๋ฐ์ดํ„ฐ๋“ค์ด ๊ณต์œ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ์™„์ „ํ•œ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ฒŒ ๋œ๋‹ค. ๋”ฐ๋ผ์„œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์–ผ๋งˆ๋‚˜ ์˜์กดํ•˜์ง€ ์•Š๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ• ์ง€ ๋˜๋Š” ๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค ์ƒํƒœ๋ฅผ ํ…Œ์ŠคํŠธ ์ด์ „์œผ๋กœ ๋Œ๋ฆด์ง€์— ๋Œ€ํ•ด์„œ ์‹ ๊ฒฝ์„ ์จ์•ผ ํ•œ๋‹ค. image

# - Domain(POJO) ๊ณ„์ธต

  • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ POJO(Model, Utils, etc...)๋Š” JUnit์œผ๋กœ ํ…Œ์ŠคํŠธ
  • ๊ฐ์ฒด๋Š” new ์—ฐ์‚ฐ์ž(๋˜๋Š” ๋นŒ๋”)๋กœ ๊ฐ„๋‹จํžˆ ์ธ์Šคํ„ด์Šคํ™”
  • ๊ฐ๊ฐ์˜ ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํ–‰๋˜๊ธฐ ์ „์— @BeforeEach์—์„œ ์ธ์Šคํ„ด์Šค ์ดˆ๊ธฐํ™”
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฉ๋ฆฌ๋ฅผ ๊ฑฑ์ •ํ•  ํ•„์š” ์—†์Œ
private Question question;

@BeforeEach
void setUp(){
    question = Question.builder()
        .userId(1L)
        .title(TEST_QUETION_TITLE)
        .content(TEST_QUESTION_CONTENT)
        .build();
}

@DisplayName("์กฐํšŒ์ˆ˜ ์ดˆ๊ธฐ๊ฐ’ ํ™•์ธ")
@Test
void initValueOfVisits(){
    assertThat(question.getVisits().getVisitCount()).isEqualTo(0L);
}

@DisplayName("์กฐํšŒ์ˆ˜ ์ฆ๊ฐ€")
@Test
void increaseVisits(){
    question.increaseVisits();
    assertThat(question.getVisits().getVisitCount()).isEqualTo(1L);
}

# - Service ๊ณ„์ธต

  • ์‹ค์งˆ์ ์ธ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ˆ˜ํ–‰
  • ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ
  • ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๋ฉด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ƒํƒœ ๋ณ€๊ฒฝ
  • ํ…Œ์ŠคํŠธ ๊ฐ„ ๊ฒฉ๋ฆฌ๊ฐ€ ํ•„์š”
  • ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ณ„์ธต๊ตฌ์กฐ๋กœ ์ด๋ฃจ์–ด์ ธ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์‹ค์ƒ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๊ฐ€ ๋˜๋ฒ„๋ฆผ
  • @Transactional์„ ์‚ฌ์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ๊ฐ€ ์ข…๋ฃŒ๋˜๋ฉด rollback๊ฐ€๋Šฅ
  • Mockito๋ฅผ ์ด์šฉํ•˜๋ฉด ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ๊ฒฉ๋ฆฌ๋ฅผ ๊ณ ๋ฏผํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

# - Controller ๊ณ„์ธต

  • @SpringBootTest
    • Spring IoC๋กœ ์‹ค์ œ ์ปจํŠธ๋กค๋Ÿฌ ๋นˆ์„ ์‚ฌ์šฉํ•ด์„œ ํ…Œ์ŠคํŠธ
    • ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์‚ฌ์šฉ
    • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ
  • @WebMvcTest
    • MockMvc RestAPI ํด๋ผ์ด์–ธํŠธ ํ…Œ์ŠคํŠธ ๋„๊ตฌ ์‚ฌ์šฉ
    • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰

# - Repository ๊ณ„์ธต

  • @DataJpaTest
    • Slice Test ์ง„ํ–‰
    • In Memory๋กœ ํ…Œ์ŠคํŠธ ์ˆ˜ํ–‰
    • ์ž๋™์œผ๋กœ @Transactional(rollback=true)์ด ์‚ฌ์šฉ๋จ

# ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ

  • ์‹œ์Šคํ…œ์ด ์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ์‚ฌ์šฉ๋  ์ค€๋น„๊ฐ€ ๋˜์—ˆ๋Š”์ง€ ์ตœ์ข…์ ์œผ๋กœ ํ™•์ธํ•˜๋Š” ๋‹จ๊ณ„
  • ์‹ค์ œ ์šด์˜ํ™˜๊ฒฝ์— ๋งž๊ฒŒ ์„œ๋ฒ„๋ฅผ ๋„์šฐ๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ์‚ฌ์šฉ
  • ํ…Œ์ŠคํŠธ ๊ฒฉ๋ฆฌ๋ฅผ ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š์œผ๋ฉด ํ…Œ์ŠคํŠธ๊ฐ€ ์‹คํŒจํ•˜๊ธฐ ์‰ฌ์›€
  • ํ…Œ์ŠคํŠธ ๋‹จ์œ„๊ฐ€ ์ปค์„œ ํ•œ๋ฒˆ ์‹คํŒจํ•˜๋ฉด ๋””๋ฒ„๊น…ํ•˜๊ธฐ ๊นŒ๋‹ค๋กœ์›€
  • Mock ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ์‹ค์ œ ๋นˆ์„ ์‚ฌ์šฉ

# ์ธ์ˆ˜ํ…Œ์ŠคํŠธ ๋ฐฉ๋ฒ•

  1. @Transactional : ์ธ์ˆ˜ ํ…Œ์ŠคํŠธ์—์„œ ์ œ๋Œ€๋กœ ์ž‘๋™ํ•˜์ง€ ์•Š์Œ. ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” http client ์ชฝ๊ณผ ์‹ค์ œ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์„œ๋ฒ„๋กœ์ง์ด ์„œ๋กœ ๋‹ค๋ฅธ ์“ฐ๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋œ๋‹ค. ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์—์„œ ์–ด๋…ธํ…Œ์ด์…˜์„ ๋กค๋ฐฑ ์ „๋žต์œผ๋กœ ํ•ด๋‘์–ด๋„, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๋Š” ์„œ๋ฒ„ ์‚ฌ์ด๋“œ ํŠธ๋žœ์žญ์…˜์€ ๊ทธ ํ…Œ์ŠคํŠธ ์ฝ”๋“œ์˜ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ๋ณ€ํ•˜๊ฒŒ ๋œ๋‹ค. image

  2. ๋งค๋ฒˆ ํ…Œ์ŠคํŠธ ์ข…๋ฃŒ์‹œ ์ƒ์„ฑํ•œ ํ”ฝ์Šค์ฒ˜ ๋ฐ ๋ฐ์ดํ„ฐ ์‚ญ์ œ image

  3. ๋งค๋ฒˆ ํ…Œ์ŠคํŠธ ์ข…๋ฃŒ์‹œ ํ…Œ์ด๋ธ” Truncate

  • Delete๋ณด๋‹ค Truncate๊ฐ€ ์ข‹์€ ์ด์œ 

    • ํŠธ๋žœ์žญ์…˜ ๋กœ๊ทธ ๊ณต๊ฐ„์„ ์ ๊ฒŒ ์ฐจ์ง€
    • ์ฟผ๋ฆฌ ์‹คํ–‰์‹œ ํ–‰๋‹จ์œ„๋กœ ๋ฝ์„ ๊ฑธ์ง€ ์•Š์Œ
  • 3-1 @Sql๋กœ SQL ํŒŒ์ผ ์‹คํ–‰ image

  • 3-2 EntityManager ์ด์šฉ(๋ณด์Šค๋…๋‹˜์ด ์ถ”์ฒœํ•˜๋Š” ๋ฐฉ์‹) ์—”ํ‹ฐํ‹ฐ ๋งค๋‹ˆ์ €๋กœ ์ฟผ๋ฆฌ๋ฅผ ์ง์ ‘ ๋งŒ๋“ค์–ด์„œ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹. ์—”ํ‹ฐํ‹ฐ์— ์žˆ๋Š” ํ…Œ์ด๋ธ” ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ ์˜จ ํ›„ ๋ฆฌ์ŠคํŠธ์— ์ €์žฅ image

๋ฐ์ดํ„ฐ ๋ฒ ์ด์Šค๋ฅผ ์ฃผ์ž… ๋ฐ›๊ณ  ํ…Œ์ŠคํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ง์ „ @BeforeEach์—์„œ ํ…Œ์ด๋ธ” ์ด๋ฆ„์„ ์กฐ์‚ฌํ•œ ํ›„ Truncate๋ฅผ ์‹คํ–‰. ์ด๋ ‡๊ฒŒ ๋งŒ๋“ค์–ด ๋‘๋ฉด ์ถ”ํ›„ ์—”ํ‹ฐํ‹ฐ๊ฐ€ ์ถ”๊ฐ€๋˜๊ฑฐ๋‚˜ ์‚ญ์ œ๋  ๋•Œ ๋™์ ์œผ๋กœ ํ…Œ์ด๋ธ”์„ ์กฐ์‚ฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ…Œ์ŠคํŠธ ๊ฒฉ๋ฆฌ์— ํˆฌ์ž…๋˜๋Š” ๋น„์šฉ์„ ์ค„์ผ ์ˆ˜ ์žˆ์Œ

image

# ์ •๋ฆฌ

  • ์ž˜๊ฒฉ๋ฆฌ๋œ ํ…Œ์ŠคํŠธ๋Š” ์œ ์ง€๋ณด์ˆ˜๊ฐ€ ์ˆ˜์›”
  • ๋”์šฑ ์•ˆ์ „ํ•œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์œผ๋กœ ์ฝ”๋“œ์˜ ํ’ˆ์งˆ ๋ณด์žฅ
Last update: September 13, 2022 21:44
Contributors: ahnjs