diff --git a/README.md b/README.md index 5fa2560..244cad1 100644 --- a/README.md +++ b/README.md @@ -1 +1,130 @@ # java-lotto-precourse + +> 로또 맞게 해주세요...ㅠ + +
+ 과제 세부 내용 + +## 과제 내용 +로또 게임 기능을 구현해야 한다. 로또 게임은 아래와 같은 규칙으로 진행된다. +``` +- 로또 번호의 숫자 범위는 1~45까지이다. +- 1개의 로또를 발행할 때 중복되지 않는 6개의 숫자를 뽑는다. +- 당첨 번호 추첨 시 중복되지 않는 숫자 6개와 보너스 번호 1개를 뽑는다. +- 당첨은 1등부터 5등까지 있다. 당첨 기준과 금액은 아래와 같다. + - 1등: 6개 번호 일치 / 2,000,000,000원 + - 2등: 5개 번호 + 보너스 번호 일치 / 30,000,000원 + - 3등: 5개 번호 일치 / 1,500,000원 + - 4등: 4개 번호 일치 / 50,000원 + - 5등: 3개 번호 일치 / 5,000원 +``` +- 로또 구입 금액을 입력하면 구입 금액에 해당하는 만큼 로또를 발행해야 한다. +- 로또 1장의 가격은 1,000원이다. +- 당첨 번호와 보너스 번호를 입력받는다. +- 사용자가 구매한 로또 번호와 당첨 번호를 비교하여 당첨 내역 및 수익률을 출력하고 로또 게임을 종료한다. +- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`를 발생시키고, "[ERROR]"로 시작하는 에러 메시지를 출력 후 그 부분부터 입력을 다시 받는다. + - `Exception`이 아닌 `IllegalArgumentException`, `IllegalStateException` 등과 같은 명확한 유형을 처리한다. + +### 입출력 +- 입력 + - 로또 구입 금액 + - 당첨 번호 6개 + - 보너스 번호 +- 출력 + - 발행한 로또 수량 및 번호 + - 당첨 내역 + - 수익률 + - (예외 문구) + +ex) + +``` +구입금액을 입력해 주세요. +8000 + +8개를 구매했습니다. +[8, 21, 23, 41, 42, 43] +[3, 5, 11, 16, 32, 38] +[7, 11, 16, 35, 36, 44] +[1, 8, 11, 31, 41, 42] +[13, 14, 16, 38, 42, 45] +[7, 11, 30, 40, 42, 43] +[2, 13, 22, 32, 38, 45] +[1, 3, 5, 14, 22, 45] + +당첨 번호를 입력해 주세요. +1,2,3,4,5,6 + +보너스 번호를 입력해 주세요. +7 + +당첨 통계 +--- +3개 일치 (5,000원) - 1개 +4개 일치 (50,000원) - 0개 +5개 일치 (1,500,000원) - 0개 +5개 일치, 보너스 볼 일치 (30,000,000원) - 0개 +6개 일치 (2,000,000,000원) - 0개 +총 수익률은 62.5%입니다. +``` + +
+ +## 코드 흐름 +- 로또 구매 금액을 입력받는다. +- 로또를 번호를 생성하고 출력한다. +- 당첨 번호를 입력받는다. +- 결과를 계산한 후 출력한다. + +```mermaid +sequenceDiagram + participant View + participant Controller + participant Model + + Controller->>View: 금액 입력 요청 + View->>Controller: 구입 금액 반환 + Controller->>Model: 구입 금액 전달 + Model-->Model: 로또 생성 + Model->>Controller: 로또 번호 반환 + Controller->>View: 로또 번호 출력 + View->>Controller: - + Controller->>View: 당첨 번호 입력 요청 + View->>Controller: 당첨 번호 반환 + Controller->>Model: 당첨 번호 전달 + Model-->Model: 당첨 여부 확인 + Model->>Controller: 결과 반환 + Controller->>View: 결과 출력 + View->>Controller: - + Controller-->Controller: 프로그램 종료 + +``` + +## 구현 기능 목록 +- 입출력 + - [ ] 구입 금액 입력 + - [ ] 당첨 번호 입력 + - [ ] 보너스 번호 입력 + - [ ] 발행한 로또 수량 및 번호 + - [ ] 당첨 내역 + - [ ] 수익률 + - [ ] 예외 +- 로또 + - [ ] 로또 생성 + - [ ] 당첨 확인 + - [ ] 수익률 계산 + +## 처리할 예외 +- 나누어 떨어지지 않는 금액 (1000 단위로 떨어지지 않을 때) + - `[ERROR] 1,000원 단위로 입력해 주세요.` +- 너무 큰 구입 금액 + - `[ERROR] $입력한 금액 보다 작은 금액을 입력해 주세요.` +- 부적절한 구입 금액 (음수 입력 등 포함, 입력 예외) + - `[ERROR] 유효한 구입 금액을 입력해 주세요` +- 부적절한 로또의 범위 (1-45 밖의 숫자) + - `[ERROR] 1부터 45 사이의 값을 입력해 주세요.` +- 중복되는 번호 / 보너스 번호 + - `[ERROR] 중복되지 않은 번호를 입력해주세요.` +- 부적절한 양식 혹은 갯수 + - `[ERROR] 당첨 번호 6개를 정확히 입력해주세요. ex)1,2,3,4,5,6` + - `[ERROR] 보너스 번호 하나를 정확히 입력해주세요. ex)7` \ No newline at end of file diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922..636a51d 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,19 @@ package lotto; +import lotto.adapter.in.InputTerminal; +import lotto.adapter.in.RandomLibrary; +import lotto.adapter.out.OutputTerminal; +import lotto.application.service.LottoService; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + LottoService lottoService = new LottoService( + new InputTerminal(), + new RandomLibrary(), + new OutputTerminal() + ); + + lottoService.run(); } } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 88fc5cf..0000000 --- a/src/main/java/lotto/Lotto.java +++ /dev/null @@ -1,20 +0,0 @@ -package lotto; - -import java.util.List; - -public class Lotto { - private final List numbers; - - public Lotto(List numbers) { - validate(numbers); - this.numbers = numbers; - } - - private void validate(List numbers) { - if (numbers.size() != 6) { - throw new IllegalArgumentException("[ERROR] 로또 번호는 6개여야 합니다."); - } - } - - // TODO: 추가 기능 구현 -} diff --git a/src/main/java/lotto/adapter/in/InputTerminal.java b/src/main/java/lotto/adapter/in/InputTerminal.java new file mode 100644 index 0000000..d4be7a0 --- /dev/null +++ b/src/main/java/lotto/adapter/in/InputTerminal.java @@ -0,0 +1,16 @@ +package lotto.adapter.in; + +import camp.nextstep.edu.missionutils.Console; +import lotto.application.port.inport.GetLottoPropertyUseCase; + +public class InputTerminal implements GetLottoPropertyUseCase { + @Override + public String getString() { + return Console.readLine(); + } + + @Override + public int getInteger() { + return Integer.parseInt(Console.readLine()); + } +} diff --git a/src/main/java/lotto/adapter/in/RandomLibrary.java b/src/main/java/lotto/adapter/in/RandomLibrary.java new file mode 100644 index 0000000..f67d6bd --- /dev/null +++ b/src/main/java/lotto/adapter/in/RandomLibrary.java @@ -0,0 +1,12 @@ +package lotto.adapter.in; + +import camp.nextstep.edu.missionutils.Randoms; +import java.util.List; +import lotto.application.port.inport.GetRandomUseCase; + +public class RandomLibrary implements GetRandomUseCase { + @Override + public List getRandomNumbers(int min, int max, int amount) { + return Randoms.pickUniqueNumbersInRange(min, max, amount); + } +} diff --git a/src/main/java/lotto/application/domain/Lotto.java b/src/main/java/lotto/application/domain/Lotto.java new file mode 100644 index 0000000..8bc8a6b --- /dev/null +++ b/src/main/java/lotto/application/domain/Lotto.java @@ -0,0 +1,42 @@ +package lotto.application.domain; + +import java.util.List; +import lotto.utils.Validator; + +public class Lotto { + private final List numbers; + + private final static int LOTTO_SIZE = 6; + private final static int LOWER_BOUND = 1; + private final static int UPPER_BOUND = 45; + + public Lotto(List numbers) { + validate(numbers); + this.numbers = numbers; + } + + private void validate(List numbers) { + try { + Validator.fitSize(numbers, LOTTO_SIZE); + Validator.hasNoDuplication(numbers); + Validator.isInRange(numbers, LOWER_BOUND, UPPER_BOUND); + } catch (RuntimeException e) { + throw new IllegalArgumentException("[ERROR] 부적절한 로또 번호 입니다.", e); + } + } + + // TODO: 추가 기능 구현 + public boolean isDuplicate(int numbers) { + return this.numbers.contains(numbers); + } + + public int countMatch(Lotto other) { + return (int) numbers.stream() + .filter(other.numbers::contains) + .count(); + } + + public boolean isMatch(int bonus) { + return numbers.contains(bonus); + } +} \ No newline at end of file diff --git a/src/main/java/lotto/application/domain/dto/WinningDataDto.java b/src/main/java/lotto/application/domain/dto/WinningDataDto.java new file mode 100644 index 0000000..433b01c --- /dev/null +++ b/src/main/java/lotto/application/domain/dto/WinningDataDto.java @@ -0,0 +1,6 @@ +package lotto.application.domain.dto; + +import lotto.application.domain.enums.LottoPrize; + +public record WinningDataDto(LottoPrize lottoPrize, int count) { +} \ No newline at end of file diff --git a/src/main/java/lotto/application/domain/enums/LottoPrize.java b/src/main/java/lotto/application/domain/enums/LottoPrize.java new file mode 100644 index 0000000..10a49d0 --- /dev/null +++ b/src/main/java/lotto/application/domain/enums/LottoPrize.java @@ -0,0 +1,51 @@ +package lotto.application.domain.enums; + +import java.util.List; + +public enum LottoPrize { + NOTHING("꽝", 0), + FIFTH_PRICE("3개 일치", 5_000), + FOURTH_PRICE("4개 일치", 50_000), + THIRD_PRICE("5개 일치", 1_500_000), + SECOND_PRICE("5개 일치, 보너스 볼 일치", 30_000_000), + FIRST_PRICE("6개 일치", 2_000_000_000); + + private final String condition; + private final int price; + + LottoPrize(String condition, int price) { + this.condition = condition; + this.price = price; + } + + public String getCondition() { + return condition; + } + + public int getPrice() { + return price; + } + + public static List getPrizeTypes() { + return List.of(FIFTH_PRICE, FOURTH_PRICE, THIRD_PRICE, SECOND_PRICE, FIRST_PRICE); + } + + public static LottoPrize getLottoPrize(int matchCount, boolean matchBonus) { + if (matchCount == 6) { + return FIRST_PRICE; + } + if (matchCount == 5 && matchBonus) { + return SECOND_PRICE; + } + if (matchCount == 5) { + return THIRD_PRICE; + } + if (matchCount == 4) { + return FOURTH_PRICE; + } + if (matchCount == 3) { + return FIFTH_PRICE; + } + return NOTHING; + } +} \ No newline at end of file diff --git a/src/main/java/lotto/application/domain/enums/MessageConstants.java b/src/main/java/lotto/application/domain/enums/MessageConstants.java new file mode 100644 index 0000000..593ddbb --- /dev/null +++ b/src/main/java/lotto/application/domain/enums/MessageConstants.java @@ -0,0 +1,21 @@ +package lotto.application.domain.enums; + +public enum MessageConstants { + PURCHASE_GUIDE("구입금액을 입력해 주세요."), + PURCHASE_RESULT("%d개를 구매했습니다."), + WINNING_NUMBER_GUIDE("당첨 번호를 입력해 주세요."), + BONUS_NUMBER_GUIDE("보너스 번호를 입력해 주세요."), + WINNING_STATUS("당첨 통계\n---"), + RESULT_LINE("%s (%,d원) - %d개"), + RETURN_RATE("총 수익률은 %.1f%%입니다.") + + + ; + private String message; + MessageConstants(String message) { + this.message = message; + } + public String getMessage() { + return message; + } +} diff --git a/src/main/java/lotto/application/domain/exceptions/ProgramTerminationException.java b/src/main/java/lotto/application/domain/exceptions/ProgramTerminationException.java new file mode 100644 index 0000000..83767bd --- /dev/null +++ b/src/main/java/lotto/application/domain/exceptions/ProgramTerminationException.java @@ -0,0 +1,7 @@ +package lotto.application.domain.exceptions; + +public class ProgramTerminationException extends IllegalArgumentException { + public ProgramTerminationException() { + super("[ERROR] 예기치 않은 문제로 프로그램을 종료합니다."); + } +} diff --git a/src/main/java/lotto/application/port/inport/GetLottoPropertyUseCase.java b/src/main/java/lotto/application/port/inport/GetLottoPropertyUseCase.java new file mode 100644 index 0000000..064a914 --- /dev/null +++ b/src/main/java/lotto/application/port/inport/GetLottoPropertyUseCase.java @@ -0,0 +1,6 @@ +package lotto.application.port.inport; + +public interface GetLottoPropertyUseCase { + String getString(); + int getInteger(); +} diff --git a/src/main/java/lotto/application/port/inport/GetRandomUseCase.java b/src/main/java/lotto/application/port/inport/GetRandomUseCase.java new file mode 100644 index 0000000..50643ea --- /dev/null +++ b/src/main/java/lotto/application/port/inport/GetRandomUseCase.java @@ -0,0 +1,7 @@ +package lotto.application.port.inport; + +import java.util.List; + +public interface GetRandomUseCase { + List getRandomNumbers(int min, int max, int amount); +} diff --git a/src/main/java/lotto/application/port/outport/LottoPort.java b/src/main/java/lotto/application/port/outport/LottoPort.java new file mode 100644 index 0000000..39af2ad --- /dev/null +++ b/src/main/java/lotto/application/port/outport/LottoPort.java @@ -0,0 +1,12 @@ +package lotto.application.port.outport; + +import java.util.List; +import lotto.application.domain.enums.MessageConstants; + +public interface LottoPort { + void sendMessage(MessageConstants message); + void sendMessage(MessageConstants message, Object... params); + void sendMessage(String message); + void clear(); + void printLottoNumbers(List numbers); +} diff --git a/src/main/java/lotto/application/service/LottoService.java b/src/main/java/lotto/application/service/LottoService.java new file mode 100644 index 0000000..c3790ad --- /dev/null +++ b/src/main/java/lotto/application/service/LottoService.java @@ -0,0 +1,132 @@ +package lotto.application.service; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import lotto.application.domain.Lotto; +import lotto.application.domain.enums.LottoPrize; +import lotto.application.domain.enums.MessageConstants; +import lotto.application.domain.exceptions.ProgramTerminationException; +import lotto.application.port.inport.GetLottoPropertyUseCase; +import lotto.application.port.inport.GetRandomUseCase; +import lotto.application.port.outport.LottoPort; +import lotto.utils.Validator; + +public class LottoService { + private final GetLottoPropertyUseCase getLottoPropertyUseCase; + private final GetRandomUseCase getRandomUseCase; + private final LottoPort lottoPort; + + public LottoService(GetLottoPropertyUseCase getLottoPropertyUseCase, + GetRandomUseCase getRandomUseCase, LottoPort lottoPort) { + this.getLottoPropertyUseCase = getLottoPropertyUseCase; + this.getRandomUseCase = getRandomUseCase; + this.lottoPort = lottoPort; + } + + public void run() { + try { + final int amount = repeat(this::getAmount); + lottoPort.clear(); + List lottoNumbers = IntStream.range(0, amount).mapToObj(i -> new Lotto(purchase())).toList(); + lottoPort.clear(); + final Lotto lotto = repeat(this::getLotto); + lottoPort.clear(); + final int bonus = repeat(() -> getBonusNumber(lotto)); + lottoPort.clear(); + printResult(lotto, bonus, lottoNumbers, amount); + } catch (ProgramTerminationException e) { + lottoPort.sendMessage(e.getMessage()); + } + } + + private int getAmount() { + try { + lottoPort.sendMessage(MessageConstants.PURCHASE_GUIDE); + int res = getLottoPropertyUseCase.getInteger(); + Validator.isDividedByThousand(res); + res /= 1000; + lottoPort.sendMessage(MessageConstants.PURCHASE_RESULT, res); + return res; + } catch (NoSuchElementException e) { + throw new ProgramTerminationException(); + } catch (Exception e) { + throw new IllegalArgumentException("[ERROR] 가격이 잘못 입력되었습니다."); + } + } + + private Lotto getLotto() { + try { + lottoPort.sendMessage(MessageConstants.WINNING_NUMBER_GUIDE); + String res = getLottoPropertyUseCase.getString(); + return new Lotto( + Arrays.stream(res.split(",")) + .map(String::trim) + .map(Integer::parseInt) + .toList() + ); + } catch (NoSuchElementException e) { + throw new ProgramTerminationException(); + } catch (Exception e) { + throw new IllegalArgumentException("[ERROR] 로또 번호가 잘못 입력되었습니다."); + } + } + + private int getBonusNumber(Lotto lotto) { + try { + lottoPort.sendMessage(MessageConstants.BONUS_NUMBER_GUIDE); + int res = getLottoPropertyUseCase.getInteger(); + if (lotto.isDuplicate(res)) { + throw new IllegalArgumentException(); + } + return res; + } catch (NoSuchElementException e) { + throw new ProgramTerminationException(); + } catch (Exception e) { + throw new IllegalArgumentException("[ERROR] 보너스 숫자가 잘못 입력되었습니다."); + } + } + + private T repeat(Supplier supplier) { + while (true) { + try { + return supplier.get(); + } catch (ProgramTerminationException e) { + throw new ProgramTerminationException(); + } catch (RuntimeException exception) { + lottoPort.sendMessage(exception.getMessage()); + } + } + } + + private List purchase() { + List numbers = getRandomUseCase.getRandomNumbers(1, 45, 6); + lottoPort.printLottoNumbers(numbers); + return numbers; + } + + private void printResult(Lotto lotto, int bonusNumber, List purchased, int amount) { + Map result = purchased.stream() + .map(other -> LottoPrize.getLottoPrize(other.countMatch(lotto), other.isMatch(bonusNumber))) + .collect(Collectors.groupingBy( + Function.identity(), + Collectors.counting() + )); + lottoPort.sendMessage(MessageConstants.WINNING_STATUS); + long sum = Stream.of(LottoPrize.FIFTH_PRICE, LottoPrize.FOURTH_PRICE, LottoPrize.THIRD_PRICE, + LottoPrize.SECOND_PRICE, LottoPrize.FIRST_PRICE) + .peek(prize -> + lottoPort.sendMessage(MessageConstants.RESULT_LINE, + prize.getCondition(), + prize.getPrice(), + result.getOrDefault(prize, 0L))) + .reduce(0L, (acc, prize) -> acc + (prize.getPrice() * result.getOrDefault(prize, 0L)), Long::sum); + lottoPort.sendMessage(MessageConstants.RETURN_RATE, (float) ((double) sum / (1000L * amount) * 100)); + } +} diff --git a/src/main/java/lotto/utils/Validator.java b/src/main/java/lotto/utils/Validator.java new file mode 100644 index 0000000..17171d8 --- /dev/null +++ b/src/main/java/lotto/utils/Validator.java @@ -0,0 +1,38 @@ +package lotto.utils; + +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +public class Validator { + public static void fitSize(Collection collection, int size) { + if (collection.size() != size) { + throw new IllegalStateException("[ERROR] size mismatch"); + } + } + + public static void hasNoDuplication(List itemList) { + if (new HashSet<>(itemList).size() != itemList.size()) { + throw new IllegalStateException("[ERROR] Duplicated item exist."); + }; + } + + public static void isInRange(int value, int min, int max) { + if (value < min || value > max) { + throw new IllegalStateException("[ERROR] Invalid range."); + } + } + + public static void isInRange(List values, int min, int max) { + if (!values.stream().allMatch(v -> v >= min && v <= max)) { + throw new IllegalStateException("[ERROR] Invalid range."); + } + } + + public static void isDividedByThousand(int value) { + if (value % 1000 != 0) { + throw new IllegalStateException("[ERROR] Invalid divided thousand."); + } + } +} diff --git a/src/test/java/lotto/ApplicationTest.java b/src/test/java/lotto/ApplicationTest.java index a15c7d1..85a4071 100644 --- a/src/test/java/lotto/ApplicationTest.java +++ b/src/test/java/lotto/ApplicationTest.java @@ -1,14 +1,18 @@ package lotto; -import camp.nextstep.edu.missionutils.test.NsTest; -import org.junit.jupiter.api.Test; - -import java.util.List; - import static camp.nextstep.edu.missionutils.test.Assertions.assertRandomUniqueNumbersInRangeTest; import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest; import static org.assertj.core.api.Assertions.assertThat; +import camp.nextstep.edu.missionutils.test.NsTest; +import java.util.List; +import java.util.stream.Stream; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + class ApplicationTest extends NsTest { private static final String ERROR_MESSAGE = "[ERROR]"; @@ -54,8 +58,106 @@ class ApplicationTest extends NsTest { }); } + @Test + void 로또번호_중복_Error1() { + assertSimpleTest(() -> { + run("5000", "1,2,3,3,5,6", "7"); + assertThat(output()).contains(ERROR_MESSAGE); + }); + } + + @Test + void 로또번호_중복_Error2() { + assertSimpleTest(() -> { + run("5000", "1,2,3,4,5,6", "4"); + assertThat(output()).contains(ERROR_MESSAGE); + }); + } + + @Test + void 로또번호_범위_Error() { + assertSimpleTest(() -> { + run("5000", "0,2,3,4,5,6", "7"); + assertThat(output()).contains(ERROR_MESSAGE); + + run("5000", "1,2,3,4,5,46", "7"); + assertThat(output()).contains(ERROR_MESSAGE); + }); + } + + @Test + void 로또번호_갯수_Error() { + assertSimpleTest(() -> { + runException("5000", "1,2,3,4,5", "7"); + assertThat(output()).contains(ERROR_MESSAGE); + + runException("5000", "1,2,3,4,5,6,7", "7"); + assertThat(output()).contains(ERROR_MESSAGE); + }); + } + + @ParameterizedTest + @MethodSource("provideNumbersForTest") + @DisplayName("로또 당첨 결과 테스트") + void 로또_당첨_등수_확인(String purchaseAmount, String winningNumbers, String bonusNumber, String expectedOutput) { + assertRandomUniqueNumbersInRangeTest( + () -> { + run(purchaseAmount, winningNumbers, bonusNumber); + assertThat(output()).contains(expectedOutput); + }, + List.of(1, 2, 3, 4, 5, 6) + ); + } + + static Stream provideNumbersForTest() { + return Stream.of( + Arguments.of("1000", "1,2,3,43,44,45", "7", "3개 일치 (5,000원) - 1개"), + Arguments.of("1000", "1,2,3,4,44,45", "7", "4개 일치 (50,000원) - 1개"), + Arguments.of("1000", "1,2,3,4,5,45", "7", "5개 일치 (1,500,000원) - 1개"), + Arguments.of("1000", "1,2,3,4,5,45", "6", "5개 일치, 보너스 볼 일치 (30,000,000원) - 1개"), + Arguments.of("1000", "1,2,3,4,5,6", "7", "6개 일치 (2,000,000,000원) - 1개") + + ); + } + + @Test + void 수익률_반올림_테스트() { + assertRandomUniqueNumbersInRangeTest( + () -> { + run("3000", "1,2,3,4,5,6", "7"); + try { + assertThat(output()).contains(ERROR_MESSAGE); + } catch (AssertionError e) { + assertThat(output()).contains("총 수익률은 166.7%입니다."); + } + }, + List.of(1, 2, 3, 43, 44, 45), + List.of(40, 41, 42, 43, 44, 45), + List.of(40, 41, 42, 43, 44, 45) + ); + } + + @Test + @DisplayName("죽지도 않고 돌아온 정수 오버플로우") + void OverflowTest() { + assertRandomUniqueNumbersInRangeTest( + () -> { + run("2000", "1,2,3,4,5,6", "7"); + try { + assertThat(output()).contains(ERROR_MESSAGE); + } catch (AssertionError e) { + assertThat(output()).contains("6개 일치 (2,000,000,000원) - 2개"); + assertThat(output()).contains("총 수익률은 200000000.0%입니다."); + } + }, + List.of(1, 2, 3, 4, 5, 6), + List.of(1, 2, 3, 4, 5, 6), + List.of(1, 2, 3, 4, 5, 6) + ); + } + @Override public void runMain() { Application.main(new String[]{}); } -} +} \ No newline at end of file diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 309f4e5..b266590 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,6 @@ package lotto; +import lotto.application.domain.Lotto; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test;