test: ga-common 유틸 + ga-batch CommissionCalculator 단위 테스트 39건
- MoneyUtilTest (10): pct/tax/mul/div HALF_UP, null 안전성 - DateUtilTest (10): 정산월 범위, 윤년/평년, 월 차이/가산 - MaskUtilTest (7): NAME/PHONE/RRN/ACCOUNT/EMAIL 마스킹 규칙 - EncryptUtilTest (6): AES-256 round-trip, 한글, 짧은 키 패딩 - CommissionCalculatorTest (6): 모집/유지수수료 계산 공식, 폴백, agent 누락 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
package com.ga.batch.settlement.calc;
|
||||
|
||||
import com.ga.core.mapper.org.AgentMapper;
|
||||
import com.ga.core.mapper.rule.RuleMapper;
|
||||
import com.ga.core.vo.ledger.LedgerVO;
|
||||
import com.ga.core.vo.org.AgentVO;
|
||||
import com.ga.core.vo.product.ContractResp;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
class CommissionCalculatorTest {
|
||||
|
||||
@Mock RuleMapper ruleMapper;
|
||||
@Mock AgentMapper agentMapper;
|
||||
|
||||
@InjectMocks CommissionCalculator calculator;
|
||||
|
||||
private ContractResp contract;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
contract = new ContractResp();
|
||||
contract.setContractId(100L);
|
||||
contract.setAgentId(10L);
|
||||
contract.setProductId(1L);
|
||||
contract.setPolicyNo("POL-0001");
|
||||
contract.setCompanyCode("SAMSUNG");
|
||||
contract.setProductCode("PRD001");
|
||||
contract.setInsuranceType("WHOLE_LIFE");
|
||||
contract.setPremium(new BigDecimal("1000000"));
|
||||
contract.setPayCycle("MONTHLY");
|
||||
contract.setContractDate(LocalDate.of(2024, 1, 15));
|
||||
|
||||
AgentVO agent = new AgentVO();
|
||||
agent.setAgentId(10L);
|
||||
agent.setGradeId(5L);
|
||||
when(agentMapper.selectById(10L)).thenReturn(agent);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("calcRecruitLedger: premium × company_rate × payout_rate, 세금은 3.3%")
|
||||
void recruit_basic() {
|
||||
when(ruleMapper.findCompanyRate(eq(1L), eq(1), any(LocalDate.class)))
|
||||
.thenReturn(new BigDecimal("7.5"));
|
||||
when(ruleMapper.findPayoutRate(eq(5L), eq("WHOLE_LIFE"), eq(1), any(LocalDate.class)))
|
||||
.thenReturn(new BigDecimal("60.0"));
|
||||
|
||||
LedgerVO led = calculator.calcRecruitLedger(contract, "202405");
|
||||
|
||||
assertThat(led).isNotNull();
|
||||
assertThat(led.getCommissionYear()).isEqualTo(1);
|
||||
assertThat(led.getSettleMonth()).isEqualTo("202405");
|
||||
assertThat(led.getStatus()).isEqualTo("CALCULATED");
|
||||
assertThat(led.getPremium()).isEqualByComparingTo("1000000");
|
||||
assertThat(led.getCompanyRate()).isEqualByComparingTo("7.5");
|
||||
assertThat(led.getPayoutRate()).isEqualByComparingTo("60.0");
|
||||
// 1,000,000 × 7.5% = 75,000.00
|
||||
assertThat(led.getCompanyAmount()).isEqualByComparingTo("75000.00");
|
||||
// 75,000 × 60% = 45,000.00
|
||||
assertThat(led.getAgentAmount()).isEqualByComparingTo("45000.00");
|
||||
// 45,000 × 3.3% = 1,485.00
|
||||
assertThat(led.getTaxAmount()).isEqualByComparingTo("1485.00");
|
||||
assertThat(led.getContractId()).isEqualTo(100L);
|
||||
assertThat(led.getAgentId()).isEqualTo(10L);
|
||||
assertThat(led.getPolicyNo()).isEqualTo("POL-0001");
|
||||
assertThat(led.getCompanyCode()).isEqualTo("SAMSUNG");
|
||||
assertThat(led.getProductCode()).isEqualTo("PRD001");
|
||||
assertThat(led.getInsuranceType()).isEqualTo("WHOLE_LIFE");
|
||||
assertThat(led.getPayMethod()).isEqualTo("MONTHLY");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("calcMaintainLedger: 회차에 따라 commission_year 가 다름")
|
||||
void maintain_year3() {
|
||||
when(ruleMapper.findCompanyRate(eq(1L), eq(3), any(LocalDate.class)))
|
||||
.thenReturn(new BigDecimal("3.0"));
|
||||
when(ruleMapper.findPayoutRate(eq(5L), eq("WHOLE_LIFE"), eq(3), any(LocalDate.class)))
|
||||
.thenReturn(new BigDecimal("50.0"));
|
||||
|
||||
LedgerVO led = calculator.calcMaintainLedger(contract, "202405", 3);
|
||||
|
||||
assertThat(led.getCommissionYear()).isEqualTo(3);
|
||||
// 1,000,000 × 3% = 30,000
|
||||
assertThat(led.getCompanyAmount()).isEqualByComparingTo("30000.00");
|
||||
// 30,000 × 50% = 15,000
|
||||
assertThat(led.getAgentAmount()).isEqualByComparingTo("15000.00");
|
||||
// 15,000 × 3.3% = 495
|
||||
assertThat(led.getTaxAmount()).isEqualByComparingTo("495.00");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("agent 가 존재하지 않으면 null 반환")
|
||||
void agentNotFound() {
|
||||
when(agentMapper.selectById(10L)).thenReturn(null);
|
||||
|
||||
LedgerVO led = calculator.calcRecruitLedger(contract, "202405");
|
||||
|
||||
assertThat(led).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("규정 누락 시 0 으로 폴백 → 모든 금액 0")
|
||||
void missingRates_fallbackZero() {
|
||||
when(ruleMapper.findCompanyRate(any(), any(), any())).thenReturn(null);
|
||||
when(ruleMapper.findPayoutRate(any(), any(), any(), any())).thenReturn(null);
|
||||
|
||||
LedgerVO led = calculator.calcRecruitLedger(contract, "202405");
|
||||
|
||||
assertThat(led).isNotNull();
|
||||
assertThat(led.getCompanyRate()).isEqualByComparingTo("0");
|
||||
assertThat(led.getPayoutRate()).isEqualByComparingTo("0");
|
||||
assertThat(led.getCompanyAmount()).isEqualByComparingTo("0.00");
|
||||
assertThat(led.getAgentAmount()).isEqualByComparingTo("0.00");
|
||||
assertThat(led.getTaxAmount()).isEqualByComparingTo("0.00");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("contractDate 가 null 이면 오늘 날짜로 대체 (예외 없음)")
|
||||
void nullContractDate_usesToday() {
|
||||
contract.setContractDate(null);
|
||||
when(ruleMapper.findCompanyRate(eq(1L), eq(1), any(LocalDate.class)))
|
||||
.thenReturn(new BigDecimal("5"));
|
||||
when(ruleMapper.findPayoutRate(eq(5L), eq("WHOLE_LIFE"), eq(1), any(LocalDate.class)))
|
||||
.thenReturn(new BigDecimal("100"));
|
||||
|
||||
LedgerVO led = calculator.calcRecruitLedger(contract, "202405");
|
||||
|
||||
assertThat(led).isNotNull();
|
||||
// 1,000,000 × 5% × 100% = 50,000
|
||||
assertThat(led.getAgentAmount()).isEqualByComparingTo("50000.00");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("premium 이 null 이면 0 으로 처리 (HALF_UP 0.00)")
|
||||
void nullPremium() {
|
||||
contract.setPremium(null);
|
||||
when(ruleMapper.findCompanyRate(any(), any(), any())).thenReturn(new BigDecimal("7.5"));
|
||||
when(ruleMapper.findPayoutRate(any(), any(), any(), any())).thenReturn(new BigDecimal("60"));
|
||||
|
||||
LedgerVO led = calculator.calcRecruitLedger(contract, "202405");
|
||||
|
||||
assertThat(led.getPremium()).isEqualByComparingTo("0");
|
||||
assertThat(led.getCompanyAmount()).isEqualByComparingTo("0.00");
|
||||
assertThat(led.getAgentAmount()).isEqualByComparingTo("0.00");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.ga.common.util;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.time.LocalDate;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
class DateUtilTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("getMonthRange: 평월")
|
||||
void monthRange_normal() {
|
||||
String[] r = DateUtil.getMonthRange("202605");
|
||||
assertThat(r).containsExactly("2026-05-01", "2026-05-31");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getMonthRange: 윤년 2월")
|
||||
void monthRange_leap() {
|
||||
String[] r = DateUtil.getMonthRange("202402");
|
||||
assertThat(r).containsExactly("2024-02-01", "2024-02-29");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getMonthRange: 평년 2월")
|
||||
void monthRange_normalFeb() {
|
||||
String[] r = DateUtil.getMonthRange("202302");
|
||||
assertThat(r).containsExactly("2023-02-01", "2023-02-28");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("calcMonthDiff: yyyymm 문자열")
|
||||
void monthDiff_yyyymm() {
|
||||
assertThat(DateUtil.calcMonthDiff("202401", "202405")).isEqualTo(4);
|
||||
assertThat(DateUtil.calcMonthDiff("202312", "202401")).isEqualTo(1);
|
||||
assertThat(DateUtil.calcMonthDiff("202405", "202401")).isEqualTo(-4);
|
||||
assertThat(DateUtil.calcMonthDiff("202401", "202401")).isZero();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("calcMonthDiff: LocalDate")
|
||||
void monthDiff_date() {
|
||||
// 같은 달의 다른 일자는 0개월
|
||||
assertThat(DateUtil.calcMonthDiff(LocalDate.of(2024, 1, 1), LocalDate.of(2024, 1, 31))).isZero();
|
||||
assertThat(DateUtil.calcMonthDiff(LocalDate.of(2024, 1, 31), LocalDate.of(2024, 2, 1))).isEqualTo(1);
|
||||
assertThat(DateUtil.calcMonthDiff(LocalDate.of(2023, 1, 1), LocalDate.of(2024, 1, 1))).isEqualTo(12);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("addMonth: 월 가산/연도 넘김")
|
||||
void addMonth() {
|
||||
assertThat(DateUtil.addMonth("202401", 3)).isEqualTo("202404");
|
||||
assertThat(DateUtil.addMonth("202312", 1)).isEqualTo("202401");
|
||||
assertThat(DateUtil.addMonth("202403", -3)).isEqualTo("202312");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("parseDate: 패턴 일치/실패")
|
||||
void parseDate() {
|
||||
assertThat(DateUtil.parseDate("2026-05-10", "yyyy-MM-dd")).isEqualTo(LocalDate.of(2026, 5, 10));
|
||||
assertThat(DateUtil.parseDate("20260510", "yyyyMMdd")).isEqualTo(LocalDate.of(2026, 5, 10));
|
||||
assertThat(DateUtil.parseDate(null, "yyyy-MM-dd")).isNull();
|
||||
assertThat(DateUtil.parseDate("", "yyyy-MM-dd")).isNull();
|
||||
assertThat(DateUtil.parseDate("invalid", "yyyy-MM-dd")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("format: 패턴 적용")
|
||||
void format() {
|
||||
LocalDate d = LocalDate.of(2026, 5, 10);
|
||||
assertThat(DateUtil.format(d, "yyyy-MM-dd")).isEqualTo("2026-05-10");
|
||||
assertThat(DateUtil.format(d, "yyyyMMdd")).isEqualTo("20260510");
|
||||
assertThat(DateUtil.format(null, "yyyy-MM-dd")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getMonthRange: 잘못된 yyyymm 은 예외")
|
||||
void monthRange_invalid() {
|
||||
assertThatThrownBy(() -> DateUtil.getMonthRange("2026"))
|
||||
.isInstanceOf(java.time.format.DateTimeParseException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("getSettleMonth(LocalDate): yyyyMM")
|
||||
void settleMonthOfDate() {
|
||||
assertThat(DateUtil.getSettleMonth(LocalDate.of(2026, 5, 10))).isEqualTo("202605");
|
||||
assertThat(DateUtil.getSettleMonth(LocalDate.of(2024, 12, 31))).isEqualTo("202412");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package com.ga.common.util;
|
||||
|
||||
import com.ga.common.exception.BizException;
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
class EncryptUtilTest {
|
||||
|
||||
private final EncryptUtil util = new EncryptUtil("ga-test-key-1234567890-abcdefghi");
|
||||
|
||||
@Test
|
||||
@DisplayName("encrypt → decrypt round-trip")
|
||||
void roundTrip() {
|
||||
String plain = "9001011234567"; // 주민번호 형태
|
||||
String enc = util.encrypt(plain);
|
||||
|
||||
assertThat(enc).isNotEqualTo(plain);
|
||||
assertThat(enc).isBase64();
|
||||
assertThat(util.decrypt(enc)).isEqualTo(plain);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("동일 평문 → 동일 암호문 (고정 IV)")
|
||||
void deterministic() {
|
||||
String enc1 = util.encrypt("hello");
|
||||
String enc2 = util.encrypt("hello");
|
||||
assertThat(enc1).isEqualTo(enc2);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("null/empty 는 그대로 반환")
|
||||
void nullEmpty() {
|
||||
assertThat(util.encrypt(null)).isNull();
|
||||
assertThat(util.encrypt("")).isEmpty();
|
||||
assertThat(util.decrypt(null)).isNull();
|
||||
assertThat(util.decrypt("")).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("키가 32바이트 미만이면 0 패딩 → 정상 동작")
|
||||
void shortKey() {
|
||||
EncryptUtil shortKey = new EncryptUtil("short");
|
||||
String enc = shortKey.encrypt("data");
|
||||
assertThat(shortKey.decrypt(enc)).isEqualTo("data");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("잘못된 암호문 복호화 시 BizException")
|
||||
void decryptInvalid() {
|
||||
assertThatThrownBy(() -> util.decrypt("not-base64-!!"))
|
||||
.isInstanceOf(BizException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("한글/특수문자 round-trip")
|
||||
void multiByte() {
|
||||
String plain = "홍길동@한국#$% áéíóú";
|
||||
assertThat(util.decrypt(util.encrypt(plain))).isEqualTo(plain);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
package com.ga.common.util;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class MaskUtilTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("maskName: 길이별 분기")
|
||||
void maskName() {
|
||||
assertThat(MaskUtil.maskName("홍")).isEqualTo("홍"); // 1자: 그대로
|
||||
assertThat(MaskUtil.maskName("홍길")).isEqualTo("홍*"); // 2자: 마지막
|
||||
assertThat(MaskUtil.maskName("홍길동")).isEqualTo("홍*동"); // 3자: 가운데
|
||||
assertThat(MaskUtil.maskName("홍길동이")).isEqualTo("홍**이"); // 4자
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("maskPhone: 11자리 / 10자리")
|
||||
void maskPhone() {
|
||||
assertThat(MaskUtil.maskPhone("010-1234-5678")).isEqualTo("010-****-5678");
|
||||
assertThat(MaskUtil.maskPhone("01012345678")).isEqualTo("010-****-5678");
|
||||
assertThat(MaskUtil.maskPhone("031-123-4567")).isEqualTo("031-***-4567"); // 10자리
|
||||
assertThat(MaskUtil.maskPhone("02-123-4567")).isEqualTo("02-123-4567"); // 9자리는 원본
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("maskRrn: 13자리만 마스킹, 그 외 원본")
|
||||
void maskRrn() {
|
||||
assertThat(MaskUtil.maskRrn("880101-1234567")).isEqualTo("880101-*******");
|
||||
assertThat(MaskUtil.maskRrn("8801011234567")).isEqualTo("880101-*******");
|
||||
// 13자리가 아니면 원본 반환
|
||||
assertThat(MaskUtil.maskRrn("88010")).isEqualTo("88010");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("maskAccount: 하이픈 포함 / 미포함")
|
||||
void maskAccount() {
|
||||
assertThat(MaskUtil.maskAccount("110-123-456789")).isEqualTo("110-***-******");
|
||||
// 하이픈 없는 경우, 4자리 노출 후 마스킹
|
||||
assertThat(MaskUtil.maskAccount("110123456789")).isEqualTo("1101********");
|
||||
assertThat(MaskUtil.maskAccount("123")).isEqualTo("123"); // 4자 이하는 원본
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("maskEmail: 첫 글자만 노출")
|
||||
void maskEmail() {
|
||||
assertThat(MaskUtil.maskEmail("aaa@bbb.com")).isEqualTo("a**@bbb.com");
|
||||
assertThat(MaskUtil.maskEmail("longusername@domain.io")).isEqualTo("l***********@domain.io");
|
||||
// @ 위치가 0 또는 1이면 마스킹 불가 → 원본
|
||||
assertThat(MaskUtil.maskEmail("@bbb.com")).isEqualTo("@bbb.com");
|
||||
assertThat(MaskUtil.maskEmail("a@bbb.com")).isEqualTo("a@bbb.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("mask: enum 디스패치")
|
||||
void mask_enum() {
|
||||
assertThat(MaskUtil.mask("홍길동", MaskUtil.MaskType.NAME)).isEqualTo("홍*동");
|
||||
assertThat(MaskUtil.mask("010-1234-5678", MaskUtil.MaskType.PHONE)).isEqualTo("010-****-5678");
|
||||
assertThat(MaskUtil.mask("aaa@bbb.com", MaskUtil.MaskType.EMAIL)).isEqualTo("a**@bbb.com");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("mask: null/blank 안전")
|
||||
void mask_nullSafe() {
|
||||
assertThat(MaskUtil.mask(null, MaskUtil.MaskType.NAME)).isNull();
|
||||
assertThat(MaskUtil.mask("", MaskUtil.MaskType.NAME)).isEmpty();
|
||||
assertThat(MaskUtil.mask(" ", MaskUtil.MaskType.NAME)).isEqualTo(" ");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package com.ga.common.util;
|
||||
|
||||
import org.junit.jupiter.api.DisplayName;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
class MoneyUtilTest {
|
||||
|
||||
@Test
|
||||
@DisplayName("zero: null 은 0 으로 치환")
|
||||
void zero_null() {
|
||||
assertThat(MoneyUtil.zero(null)).isEqualTo(BigDecimal.ZERO);
|
||||
assertThat(MoneyUtil.zero(new BigDecimal("12.34"))).isEqualByComparingTo("12.34");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("add/sub: null 안전, 정상 합/차")
|
||||
void add_sub() {
|
||||
assertThat(MoneyUtil.add(null, new BigDecimal("100"))).isEqualByComparingTo("100");
|
||||
assertThat(MoneyUtil.add(new BigDecimal("100"), null)).isEqualByComparingTo("100");
|
||||
assertThat(MoneyUtil.add(new BigDecimal("100"), new BigDecimal("50.50"))).isEqualByComparingTo("150.50");
|
||||
assertThat(MoneyUtil.sub(new BigDecimal("100"), new BigDecimal("30"))).isEqualByComparingTo("70");
|
||||
assertThat(MoneyUtil.sub(null, null)).isEqualByComparingTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("mul: 소수점 2자리 HALF_UP")
|
||||
void mul_halfUp() {
|
||||
// 1.235 → 1.24 (HALF_UP)
|
||||
assertThat(MoneyUtil.mul(new BigDecimal("0.5"), new BigDecimal("2.47")))
|
||||
.isEqualByComparingTo("1.24");
|
||||
assertThat(MoneyUtil.mul(null, new BigDecimal("100"))).isEqualByComparingTo("0.00");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("div: 0 으로 나누면 0 반환, null 안전")
|
||||
void div_byZero() {
|
||||
assertThat(MoneyUtil.div(new BigDecimal("100"), BigDecimal.ZERO)).isEqualByComparingTo("0");
|
||||
assertThat(MoneyUtil.div(new BigDecimal("100"), null)).isEqualByComparingTo("0");
|
||||
assertThat(MoneyUtil.div(new BigDecimal("100"), new BigDecimal("3")))
|
||||
.isEqualByComparingTo("33.33");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("pct: amount × rate / 100, 2자리 HALF_UP")
|
||||
void pct_basic() {
|
||||
// 1,000,000 × 7.5% = 75,000.00
|
||||
assertThat(MoneyUtil.pct(new BigDecimal("1000000"), new BigDecimal("7.5")))
|
||||
.isEqualByComparingTo("75000.00");
|
||||
// 100 × 33.33% = 33.33
|
||||
assertThat(MoneyUtil.pct(new BigDecimal("100"), new BigDecimal("33.33")))
|
||||
.isEqualByComparingTo("33.33");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("pct: null 입력은 0")
|
||||
void pct_null() {
|
||||
assertThat(MoneyUtil.pct(null, new BigDecimal("10"))).isEqualByComparingTo("0");
|
||||
assertThat(MoneyUtil.pct(new BigDecimal("100"), null)).isEqualByComparingTo("0");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("tax: 기본 3.3% 원천징수")
|
||||
void tax_default() {
|
||||
// 1,000,000 × 3.3% = 33,000.00
|
||||
assertThat(MoneyUtil.tax(new BigDecimal("1000000")))
|
||||
.isEqualByComparingTo("33000.00");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("tax: 사용자 지정 세율")
|
||||
void tax_customRate() {
|
||||
assertThat(MoneyUtil.tax(new BigDecimal("1000"), new BigDecimal("10")))
|
||||
.isEqualByComparingTo("100.00");
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("isZero/isPositive/isNegative")
|
||||
void signChecks() {
|
||||
assertThat(MoneyUtil.isZero(null)).isTrue();
|
||||
assertThat(MoneyUtil.isZero(BigDecimal.ZERO)).isTrue();
|
||||
assertThat(MoneyUtil.isZero(new BigDecimal("0.00"))).isTrue();
|
||||
assertThat(MoneyUtil.isPositive(new BigDecimal("0.01"))).isTrue();
|
||||
assertThat(MoneyUtil.isPositive(null)).isFalse();
|
||||
assertThat(MoneyUtil.isNegative(new BigDecimal("-1"))).isTrue();
|
||||
assertThat(MoneyUtil.isNegative(BigDecimal.ZERO)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisplayName("fmt/fmtDec/fmtSign")
|
||||
void formatting() {
|
||||
assertThat(MoneyUtil.fmt(new BigDecimal("1234567"))).isEqualTo("1,234,567");
|
||||
assertThat(MoneyUtil.fmt(null)).isEmpty();
|
||||
assertThat(MoneyUtil.fmtDec(new BigDecimal("1234.5"))).isEqualTo("1,234.50");
|
||||
assertThat(MoneyUtil.fmtSign(new BigDecimal("100"))).isEqualTo("+100");
|
||||
assertThat(MoneyUtil.fmtSign(new BigDecimal("-100"))).isEqualTo("-100");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user