๐Ÿ“Œ [MarketBridge] 04. ๊ฐœ๋ฐœ์ผ์ง€ - @CreatedDate ํ…Œ์ŠคํŠธํ•˜๊ธฐ

๋ชจ๊น…ยท2024๋…„ 1์›” 30์ผ
0

๊ฐœ๋ฐœ์ผ์ง€ - MarketBridge

๋ชฉ๋ก ๋ณด๊ธฐ
4/8
post-custom-banner

๐Ÿ“– @CreatedDate, @LastModifiedDate์€ ํ…Œ์ŠคํŠธ๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ๊นŒ?

@CreatedDate, @LastModifiedDate์€ JPA์—์„œ ์ฒ˜๋ฆฌํ•ด์ฃผ๋Š” ๋…€์„๋“ค์ด๋ผ์„œ ํ…Œ์ŠคํŠธ ์ž‘์„ฑ์‹œ ์–ด๋–ป๊ฒŒ ํ…Œ์ŠคํŠธํ•ด์•ผ ํ• ๊นŒ ๊ณ ๋ฏผ์ด ๋งŽ์•˜๋‹ค. (ํ˜„์žฌ @CreatedDate, @LastModifiedDate๋Š” BaseEntity์— ์กด์žฌํ•˜๋ฉฐ, ํ…Œ์ŠคํŠธํ•  ๋– ์˜ค๋ฅด์ง€ ์•Š์•˜๋‹ค..)

`public static OrderCancelReturnDetailResponseDto of(Order order, List<OrderDetail> orderDetails, String memberShip) {
        return OrderCancelReturnDetailResponseDto.builder()
        
                .orderDate(order.getCreatedAt())
                .cancelDate(order.getUpdatedAt())
                
                .orderNo(order.getOrderNo())
                .cancelReason(orderDetails.get(0).getReason())
                .productListResponseDtos(
                        orderDetails.stream()
                                .map(ProductListResponseDto::of)
                                .toList()
                )
                .cancelRefundInfoResponseDto(
                        CancelRefundInfoResponseDto.of(orderDetails, memberShip)
                )
                .build();
    }

์ด๋Ÿฐ ์ฝ”๋“œ๋Š” ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑ ํ•  ๋•Œ Date์— ๋Œ€ํ•œ ํ…Œ์ŠคํŠธ๋Š” ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅ์— ๊ฐ€๊น๋‹ค. Mockito, Mockbean๋“ฑ์„ ํ†ตํ•ด ์ฒ˜๋ฆฌ๋ฅผ ํ•ด์ฃผ๋ฉด ๋ ํ…Œ์ง€๋งŒ ์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•๋“ค์„ ์ตœ๋Œ€ํ•œ ์ง€์–‘ํ•˜๋Š” ์ž…์žฅ์—์„œ ์–ด๋–ป๊ฒŒ ํ•ด์•ผํ• ์ง€ ๊ณ ๋ฏผ์ด ์ƒ๊ฒผ๋‹ค.

์‹œ๊ฐ„์— ๋Œ€ํ•œ ๊ฒƒ์„ ์™ธ๋ถ€์—์„œ ์ œ๊ณต๋ฐ›๋Š” ๊ตฌ์กฐ๋กœ ๋ฐ”๊ฟ”์•ผ ํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

โœ๏ธ ๋ฆฌํŒฉํ† ๋ง 1

public static OrderCancelReturnDetailResponseDto of(Order order, List<OrderDetail> orderDetails, String memberShip, LocalDateTime createTime, LocalDateTime updateTime) {
        return OrderCancelReturnDetailResponseDto.builder()
        
                .orderDate(createTime)
                .cancelDate(updateTime)
                
                .orderNo(order.getOrderNo())
                .cancelReason(orderDetails.get(0).getReason())
                .productListResponseDtos(
                        orderDetails.stream()
                                .map(ProductListResponseDto::of)
                                .toList()
                )
                .cancelRefundInfoResponseDto(
                        CancelRefundInfoResponseDto.of(orderDetails, memberShip)
                )
                .build();
    }

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ…Œ์ŠคํŠธ๊ฐ€ ์–ด๋Š์ •๋„ ๊ฐ€๋Šฅํ•ด์งˆ ๊ฒƒ์œผ๋กœ ์ƒ๊ฐ๋˜์ง€๋งŒ ๋ณด๊ธฐ ์ข‹์ง€ ์•Š์•˜๋‹ค.

โœ๏ธ ๋ฆฌํŒฉํ† ๋ง 2

public static OrderCancelReturnDetailResponseDto of(Order order, List<OrderDetail> orderDetails, String memberShip, DateTimeHolder dateTimeHolder) {
        return OrderCancelReturnDetailResponseDto.builder()
        
                .orderDate(dateTimeHolder.getCreateTime(order))
                .cancelDate(dateTimeHolder.getUpdateTime(order))
                
                .orderNo(order.getOrderNo())
                .cancelReason(orderDetails.get(0).getReason())
                .productListResponseDtos(
                        orderDetails.stream()
                                .map(ProductListResponseDto::of)
                                .toList()
                )
                .cancelRefundInfoResponseDto(
                        CancelRefundInfoResponseDto.of(orderDetails, memberShip)
                )
                .build();
    }

ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ถ”์ƒํ™”ํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์•ผ ์ข‹์€ ๊ตฌ์กฐ๋กœ ๊ฐˆ ์ˆ˜ ์žˆ๋‹ค๋Š” ์ƒ๊ฐ์„ ํ•˜๊ฒŒ๋๋‹ค.

์ข€ ๋” ์ž์„ธํžˆ DateTimeHolder๋ฅผ ๋ณด๋ฉด

public interface DateTimeHolder {

    LocalDateTime getTimeNow();

    LocalDateTime getCreateTime(BaseEntity entity);

    LocalDateTime getUpdateTime(BaseEntity entity);

    LocalDateTime getDeleteTime(BaseEntity entity);
}
@Component
public class SystemDataTimeHolder implements DateTimeHolder {

    @Override
    public LocalDateTime getTimeNow() {
        return LocalDateTime.now();
    }

    @Override
    public LocalDateTime getCreateTime(BaseEntity entity) {
        return entity.getCreatedAt();
    }

    @Override
    public LocalDateTime getUpdateTime(BaseEntity entity) {
        return entity.getUpdatedAt();
    }

    @Override
    public LocalDateTime getDeleteTime(BaseEntity entity) {
        return entity.getDeletedAt();
    }
}

๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ตฌ์„ฑํ•˜์—ฌ Service์—์„œ ์ฃผ์ž…๋ฐ›์•„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•˜์˜€๋‹ค.

์ด ๊ฒฐ๊ณผ ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๋Š”๋ฐ ์ข‹์€ ๊ตฌ์กฐ๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋˜์—ˆ๋‹ค.
ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•˜๊ธฐ ์ „ DateTimeHolder๋ฅผ mockingํ•œ ํ…Œ์ŠคํŠธ์šฉ ๊ฐ์ฒด๊ฐ€ ํ•„์š”๋กœ ํ•œ๋‹ค.

public class TestDateTimeHolder implements DateTimeHolder {

    private LocalDateTime now;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    private LocalDateTime deleteTime;

    @Builder
    private TestDateTimeHolder(LocalDateTime now, LocalDateTime createTime, LocalDateTime updateTime, LocalDateTime deleteTime) {
        this.now = now;
        this.createTime = createTime;
        this.updateTime = updateTime;
        this.deleteTime = deleteTime;
    }

    @Override
    public LocalDateTime getTimeNow() {
        return now;
    }

    @Override
    public LocalDateTime getCreateTime(BaseEntity entity) {
        return createTime;
    }

    @Override
    public LocalDateTime getUpdateTime(BaseEntity entity) {
        return updateTime;
    }

    @Override
    public LocalDateTime getDeleteTime(BaseEntity entity) {
        return deleteTime;
    }
}
LocalDateTime createTime = LocalDateTime.of(2024, 1, 30, 2, 15);
        LocalDateTime updateTime = LocalDateTime.of(2024, 1, 30, 2, 20);
        TestDateTimeHolder timeHolder = TestDateTimeHolder.builder()
                .createTime(createTime)
                .updateTime(updateTime)
                .build();

        // when
        OrderCancelReturnDetailResponseDto result = OrderCancelReturnDetailResponseDto.of(order, orderDetails, WOW.getText(), timeHolder);

        // then
        assertThat(result).extracting("orderDate", "cancelDate", "orderNo", "cancelReason")
                .contains(createTime, updateTime, "123", "๋‹จ์ˆœ๋ณ€์‹ฌ");

์ด๋Ÿฐ์‹์œผ๋กœ ์ฃผ์ž…๋ฐ›์•„์„œ ์‚ฌ์šฉํ•˜๋ฉด @Mockbean, Mockito๋“ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•„๋„ ํ…Œ์ŠคํŠธ๊ฐ€ ๊ฐ€๋Šฅํ•ด์ง„๋‹ค!!!

๊ณ ๋ฏผ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์™€์„œ ๊ธฐ๋ถ„์ด ๋งค์šฐ ์ข‹์•„๋ฒ„๋ฆฐ๋‹ค~!~!

profile
๋ฉˆ์ถ”์ง€ ์•Š๊ธฐ
post-custom-banner

0๊ฐœ์˜ ๋Œ“๊ธ€