Projects/HubEleven

[동시성 처리] 재고 감소 통합 테스트 코드 4 - 단일 스레드

annovation 2026. 1. 29. 23:51

단일 스레드 환경 with Test Fixture

💡test/java/com.hubeleven.product/stock/application/fixtures/StockFixture.java

  • Stock 도메인 테스트용 StockFixture 클래스 생성
// fixtures/StockFixture.java
public class StockFixture {

    // ===== 고정 ID =====
    public static final UUID PRODUCT_ID =
            UUID.fromString("11111111-1111-1111-1111-111111111111");

    public static final UUID COMPANY_ID =
            UUID.fromString("22222222-2222-2222-2222-222222222222");

    public static final UUID HUB_ID =
            UUID.fromString("33333333-3333-3333-3333-333333333333");

    // ===== Factory Methods =====

    public static Stock createDefault() {
        return Stock.create(PRODUCT_ID, COMPANY_ID, HUB_ID, 100);
    }

    public static Stock createWithQuantity(int quantity) {
        return Stock.create(PRODUCT_ID, COMPANY_ID, HUB_ID, quantity);
    }

    public static Stock lowStock() {
        return createWithQuantity(5);
    }

    public static Stock outOfStock() {
        return createWithQuantity(0);
    }

    // ===== Builder =====

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private UUID productId = PRODUCT_ID;
        private UUID companyId = COMPANY_ID;
        private UUID hubId = HUB_ID;
        private int quantity = 100;

        public Builder productId(UUID productId) {
            this.productId = productId;
            return this;
        }

        public Builder companyId(UUID companyId) {
            this.companyId = companyId;
            return this;
        }

        public Builder hubId(UUID hubId) {
            this.hubId = hubId;
            return this;
        }

        public Builder quantity(int quantity) {
            this.quantity = quantity;
            return this;
        }

        public Stock build() {
            return Stock.create(productId, companyId, hubId, quantity);
        }
    }

    private StockFixture() {}
}

💡고정 ID

 // ===== 고정 ID =====
    public static final UUID PRODUCT_ID =
            UUID.fromString("11111111-1111-1111-1111-111111111111");

    public static final UUID COMPANY_ID =
            UUID.fromString("22222222-2222-2222-2222-222222222222");

    public static final UUID HUB_ID =
            UUID.fromString("33333333-3333-3333-3333-333333333333");

 

✅ 각 ID 추적 가능하도록 고정된 UUID 값 사용


💡Factory Methods

// ===== Factory Methods =====

    public static Stock createDefault() {
        return Stock.create(PRODUCT_ID, COMPANY_ID, HUB_ID, 100);
    }

    public static Stock createWithQuantity(int quantity) {
        return Stock.create(PRODUCT_ID, COMPANY_ID, HUB_ID, quantity);
    }

    public static Stock lowStock() {
        return createWithQuantity(5);
    }

    public static Stock outOfStock() {
        return createWithQuantity(0);
    }

 

✅ 테스트가 무엇을 검증하는지 명확히 드러나는 Factory 메서드 구현


💡Builder

// ===== Builder =====

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private UUID productId = PRODUCT_ID;
        private UUID companyId = COMPANY_ID;
        private UUID hubId = HUB_ID;
        private int quantity = 100;

        public Builder productId(UUID productId) {
            this.productId = productId;
            return this;
        }

        public Builder companyId(UUID companyId) {
            this.companyId = companyId;
            return this;
        }

        public Builder hubId(UUID hubId) {
            this.hubId = hubId;
            return this;
        }

        public Builder quantity(int quantity) {
            this.quantity = quantity;
            return this;
        }

        public Stock build() {
            return Stock.create(productId, companyId, hubId, quantity);
        }
    }

 

✅ 필요한 값으로 바꿔서 사용 가능한 Builder 패턴 구현


💡인스턴스 생성 차단

private StockFixture() {}
  • StockFixture 클래스는 객체를 생성하기 위한 클래스가 아니기 때문에 new StockFixture() 는 의미가 없다.
  • Java 에서는 생성자를 만들지 않으면 기본 생성자가 자동으로 만들어지지만, StockFixutre 는 인스턴스가 아무 역할도 하지 않기 때문에 쓸모 없는 객체 생성으로 인해 잘못된 사용 가능성이 있다.
  • 이를 위해 private 으로 인스턴스 생성을 차단한다.