diff --git a/build.gradle b/build.gradle index ee0f309..a1a06fb 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,13 @@ repositories { } dependencies { - implementation 'com.github.woowacourse-projects:mission-utils:1.0.0' + implementation 'com.github.kokodak:mission-utils:1.0.0' + + implementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' + implementation 'org.junit.jupiter:junit-jupiter-engine:5.8.1' + implementation 'org.mockito:mockito-inline:3.12.4' + implementation 'org.assertj:assertj-core:3.21.0' + implementation 'org.junit.jupiter:junit-jupiter:5.8.1' } java { @@ -19,4 +25,4 @@ java { test { useJUnitPlatform() -} +} \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index e69de29..48da283 100644 --- a/docs/README.md +++ b/docs/README.md @@ -0,0 +1,32 @@ +# 로또 +1. 입력 + 1. 금액 입력 + - 정수인지 검증 + - 0인지 검증 + - 1000원 단위인지 검증 + 2. 당첨번호 입력 + - 정수인지 검증 + - 1~45사이 정수인지 검증 + - 중복된 로또 번호가 존재하는지 검증 + - 개수가 6개인지 검증 + 3. 보너스번호 입력 + - 정수인지 검증 + - 1~45사이 정수인지 검증 + - 정규 당첨번호에 있는 수인지 검증 +2. 로또 생성 + 1. 금액//1000 만큼 로또 생성 + 2. 검증 + - 1~45사이 정수인지 검증 + - 중복된 로또 번호가 존재하는지 검증 + - 개수가 6개인지 검증 + - 오름차순인지 검증 +3. 로또 출력 + 1. 로또 수 출력 + 2. 로또 번호 출력 +4. 당첨번호와 로또 번호확인 + 1. 정규번호 6자리 와 당첨번호 비교, 5자리와 보너스 번호가 맞으면 2등 + 2. 당첨 수 계산 +5. 당첨결과 출력 + 1. 당첨 내역 출력 + 2. 수익률 출력 + diff --git a/src/main/java/lotto/Application.java b/src/main/java/lotto/Application.java index d190922..458d53b 100644 --- a/src/main/java/lotto/Application.java +++ b/src/main/java/lotto/Application.java @@ -1,7 +1,21 @@ package lotto; +import lotto.controller.LottoController; +import lotto.view.InputView; +import lotto.view.OutputView; + +import java.util.ArrayList; +import java.util.List; +import java.util.Scanner; + public class Application { public static void main(String[] args) { // TODO: 프로그램 구현 + InputView inputView = new InputView(); + OutputView outputView = new OutputView(); + LottoController lottoController = new LottoController(inputView,outputView); + lottoController.start(); + } + } diff --git a/src/main/java/lotto/Lotto.java b/src/main/java/lotto/Lotto.java deleted file mode 100644 index 519793d..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(); - } - } - - // TODO: 추가 기능 구현 -} diff --git a/src/main/java/lotto/controller/LottoController.java b/src/main/java/lotto/controller/LottoController.java new file mode 100644 index 0000000..9aea8a2 --- /dev/null +++ b/src/main/java/lotto/controller/LottoController.java @@ -0,0 +1,79 @@ +package lotto.controller; + +import lotto.domain.Lotto; +import lotto.domain.Ranking; +import lotto.domain.WinnigResult; +import lotto.util.Constants; +import lotto.util.ExceptionMessage; +import lotto.util.LottoGenerator; +import lotto.util.MoneyValidator; +import lotto.view.InputView; +import lotto.view.OutputView; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class LottoController { + private final InputView inputView; + private final OutputView outputView; + + public LottoController(InputView inputView, OutputView outputView) { + this.inputView = inputView; + this.outputView = outputView; + } + + public void start(){ + try { + int money=inputView.readMoney(); + LottoGenerator lottoGenerator = new LottoGenerator(); + + List lottos = lottoGenerator.generate(money); + List winningNumbers = inputView.readWinningNumbers(); + int bonusNum = inputView.readBonusNumber(winningNumbers); + WinnigResult winnigResult = new WinnigResult(new Lotto(winningNumbers), bonusNum); + lottoResult(lottos, winnigResult, money / 1000); + }catch (IllegalArgumentException e){ + System.out.println(e.getMessage()); + } + } + private void lottoResult(List lottoList, WinnigResult winnigResult, int ticketNum){ + Map result = setResult(); + Ranking rank; + + OutputView.printSuccessResult(); + for (int i = 0; i < lottoList.size(); i++) { + rank = winnigResult.match(lottoList.get(i)); + + result.put(rank, result.get(rank) + 1); + } + printResult(result); + printEarningRate(result, ticketNum); + } + + private void printResult(Map result) { + for (int i = Ranking.values().length - 1; i >= 0; i--) { + Ranking.values()[i].printMessage(result.get(Ranking.values()[i])); + } + } + + private void printEarningRate(Map result, int lottoAmount) { + double EarningRate = 0; + for (Ranking rank : result.keySet()) { + EarningRate = + EarningRate + ((double) (rank.getWinningAmount()) / (lottoAmount * Constants.LOTTO_PRICE) * (result.get( + rank)) * (100)); + + } + OutputView.printRevenueRate(EarningRate); + } + + private Map setResult() { + Map result = new LinkedHashMap<>(); + + for (Ranking rank : Ranking.values()) { + result.put(rank, 0); + } + return result; + } +} diff --git a/src/main/java/lotto/domain/Lotto.java b/src/main/java/lotto/domain/Lotto.java new file mode 100644 index 0000000..f72e985 --- /dev/null +++ b/src/main/java/lotto/domain/Lotto.java @@ -0,0 +1,64 @@ +package lotto.domain; + +import lotto.util.Constants; +import lotto.util.ExceptionMessage; + +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static lotto.util.ExceptionMessage.INVALID_WINNING_NUMBER_DUPLICATE; +import static lotto.util.ExceptionMessage.INVALID_WINNING_SIZE; + +public class Lotto { + private final List numbers; + + public Lotto(List numbers) { + validate(numbers); + validateDuplicateNum(numbers); + validateNumRange(numbers); + this.numbers = numbers; + Collections.sort(numbers); + } + + + private void validate(List numbers) { + if (numbers.size() != 6) { + throw new IllegalArgumentException(INVALID_WINNING_SIZE.getMessage()); + } + Set set = new HashSet<>(numbers); + if (set.size()!=6){ + throw new IllegalArgumentException(INVALID_WINNING_NUMBER_DUPLICATE.getMessage()); + } + } + private void validateDuplicateNum(List numbers) { + Set set = new HashSet<>(numbers); + if (set.size()!=6){ + throw new IllegalArgumentException(INVALID_WINNING_NUMBER_DUPLICATE.getMessage()); + } + } + private void validateNumRange(List numbers) { + + for (Integer number : numbers) { + if (number<=0 || number>45){ + throw new IllegalArgumentException(ExceptionMessage.INVALID_LOTTO_NUMBER_RANGE.getMessage()); + } + } + } + + // TODO: 추가 기능 구현 + //public void printResult + public int countMatch(List winningNum){ + return (int) numbers.stream() + .filter(winningNum::contains).count(); + } + public boolean containNum(int num){ + return numbers.contains(num); + } + + public List getNumbers() { + return numbers; + } + +} diff --git a/src/main/java/lotto/domain/Ranking.java b/src/main/java/lotto/domain/Ranking.java new file mode 100644 index 0000000..729b40f --- /dev/null +++ b/src/main/java/lotto/domain/Ranking.java @@ -0,0 +1,54 @@ +package lotto.domain; + +import lotto.view.OutputView; + +import java.util.Random; + +public enum Ranking { + FIRST(6, 2_000_000_000, "6개 일치 (2,000,000,000원) - "), // 1등 + SECOND(5, 30_000_000, "5개 일치, 보너스 볼 일치 (30,000,000원) - "), // 2등 + THIRD(5, 1_500_000, "5개 일치 (1,500,000원) - "), // 3등 + FOURTH(4, 50_000, "4개 일치 (50,000원) - "), // 4등 + FIFTH(3, 5_000, "3개 일치 (5,000원) - "), // 5등 + MISS(0, 0, ""); + Ranking(int countOfMatch, int winningAmount, String message) { + this.countOfMatch = countOfMatch; + this.winningAmount = winningAmount; + this.message = message; + } + private int countOfMatch; + private int winningAmount; + private String message; + + private static final int WINNG_MIN_COUNT=3; + public static Ranking valueOf(int countOfMatch, boolean matchBonus){ + if (countOfMatch generate(int money){ + int ticketNum=money/1000; + + OutputView.printTicketCount(ticketNum); + List lottos=new ArrayList<>(); + for (int i=0; ticketNum>i; i++){ + List lottoNum= new ArrayList<>(Randoms.pickUniqueNumbersInRange(MIN_NUM,MAX_NUM,NUM_COUNT)); + Lotto lotto = new Lotto(lottoNum); + lottos.add(lotto); + System.out.println(lotto.getNumbers()); + + } + return lottos; + } +} diff --git a/src/main/java/lotto/util/MoneyValidator.java b/src/main/java/lotto/util/MoneyValidator.java new file mode 100644 index 0000000..ea4007c --- /dev/null +++ b/src/main/java/lotto/util/MoneyValidator.java @@ -0,0 +1,26 @@ +package lotto.util; + +import static lotto.util.Constants.LOTTO_PRICE; +import static lotto.util.ExceptionMessage.*; + +public class MoneyValidator extends Validator{ + @Override + public void validate(String money) throws IllegalStateException { + validateInt(money); + validateMoneyUnit(money); + validateIsZero(money); + } + + private void validateMoneyUnit(String money){ + if (Integer.parseInt(money)% LOTTO_PRICE!=0){ + throw new IllegalArgumentException(INVALID_MONEY_UNIT.getMessage()); + } + } + + private void validateIsZero(String money){ + if(Integer.parseInt(money)==0){ + throw new IllegalArgumentException(ZERO_EXCEPTION.getMessage()); + } + } + +} diff --git a/src/main/java/lotto/util/Validator.java b/src/main/java/lotto/util/Validator.java new file mode 100644 index 0000000..08c9d83 --- /dev/null +++ b/src/main/java/lotto/util/Validator.java @@ -0,0 +1,28 @@ +package lotto.util; + +import java.util.List; + +import static lotto.util.Constants.MAX_NUM; +import static lotto.util.Constants.MIN_NUM; +import static lotto.util.ExceptionMessage.INVALID_LOTTO_NUMBER_RANGE; +import static lotto.util.ExceptionMessage.NOT_INT; + +public abstract class Validator { + abstract void validate(String input) throws IllegalStateException; +// abstract void validate(String input, List winningNums) throws IllegalStateException; + + void validateInt(String input){ + try { + Integer.parseInt(input); + }catch (NumberFormatException e){ + throw new IllegalArgumentException(NOT_INT.getMessage()); + } + } + + void validateLottoNumberRange(String lottoNumber){ + int num= Integer.parseInt(lottoNumber); + if (num< MIN_NUM || num>MAX_NUM){ + throw new IllegalArgumentException(INVALID_LOTTO_NUMBER_RANGE.getMessage()); + } + } +} diff --git a/src/main/java/lotto/util/WinningNumberValidator.java b/src/main/java/lotto/util/WinningNumberValidator.java new file mode 100644 index 0000000..72e7013 --- /dev/null +++ b/src/main/java/lotto/util/WinningNumberValidator.java @@ -0,0 +1,35 @@ +package lotto.util; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import static lotto.util.ExceptionMessage.INVALID_WINNING_NUMBER_DUPLICATE; +import static lotto.util.ExceptionMessage.INVALID_WINNING_SIZE; + +public class WinningNumberValidator extends Validator{ + @Override + public void validate(String input) throws IllegalStateException { + List winnigNumbers = new ArrayList<>(List.of(input.split(","))); + validateWinningNumberSize(winnigNumbers); + validateWinningNumberDuplicate(winnigNumbers); + for (String winnigNumber : winnigNumbers) { + validateInt(winnigNumber); + validateLottoNumberRange(winnigNumber); + } + + } + private void validateWinningNumberSize(List winngNumbers){ + if (winngNumbers.size()!=Constants.NUM_COUNT){ + throw new IllegalArgumentException(INVALID_WINNING_SIZE.getMessage()); + } + } + + private void validateWinningNumberDuplicate(List winningNumbers){ + Set set = new HashSet<>(winningNumbers); + if (set.size()!=6){ + throw new IllegalArgumentException(INVALID_WINNING_NUMBER_DUPLICATE.getMessage()); + } + } +} diff --git a/src/main/java/lotto/view/InputView.java b/src/main/java/lotto/view/InputView.java new file mode 100644 index 0000000..5cc6360 --- /dev/null +++ b/src/main/java/lotto/view/InputView.java @@ -0,0 +1,55 @@ +package lotto.view; + + +import lotto.util.BonusNumValidator; +import lotto.util.ExceptionMessage; +import lotto.util.MoneyValidator; +import lotto.util.WinningNumberValidator; +import org.kokodak.Console; + +import java.util.ArrayList; +import java.util.List; + +public class InputView { + private enum ConsoleMessage{ + INPUT_MONEY("구매금액을 입력해주세요."), + INPUT_WINNIG_NUMBER("당첨 번호를 입력해주세요."), + INPUT_BONUS_NUMBER("보너스 번호를 입력해주세요"); + private final String message; + ConsoleMessage(String message){ + this.message=message; + } + } + + public int readMoney(){ + System.out.println(ConsoleMessage.INPUT_MONEY.message); + //String money = Console.readLine(); + + String money = org.kokodak.Console.readLine(); + new MoneyValidator().validate(money); + return Integer.parseInt(money); + } + + public List readWinningNumbers(){ + System.out.println(ConsoleMessage.INPUT_WINNIG_NUMBER.message); + String input = Console.readLine(); + new WinningNumberValidator().validate(input); + List winnigNumbersString = new ArrayList<>(List.of(input.split(","))); + List winnigNumbersInteger=new ArrayList<>(); + for (String s : winnigNumbersString) { + winnigNumbersInteger.add(Integer.parseInt(s)); + } + return winnigNumbersInteger; + } + + public int readBonusNumber(List winningNums){ + System.out.println(ConsoleMessage.INPUT_BONUS_NUMBER.message); + String input = Console.readLine(); + new BonusNumValidator().validate(input); + int bonusNum=Integer.parseInt(input); + if (winningNums.contains(bonusNum) == true) { + throw new IllegalArgumentException(ExceptionMessage.INVALID_BONUS_NUM.getMessage()); + } + return bonusNum; + } +} diff --git a/src/main/java/lotto/view/OutputView.java b/src/main/java/lotto/view/OutputView.java new file mode 100644 index 0000000..1c68322 --- /dev/null +++ b/src/main/java/lotto/view/OutputView.java @@ -0,0 +1,23 @@ +package lotto.view; + +public class OutputView { + public static final String TICKET_COUNT = "개를 구매했습니다."; + + public static void printTicketCount(int count) { + System.out.println(); + System.out.println(count + TICKET_COUNT); + } + + public static void printSuccessResult() { + System.out.println("당첨 통계"); + System.out.println("---"); + } + + public static void printSuccessMessage(String message, int numberOfMatch) { + System.out.println(message + numberOfMatch + "개"); + } + + public static void printRevenueRate(double EarningRate) { + System.out.println("총 수익률은 " + String.format("%.1f", EarningRate) + "%입니다."); + } +} \ No newline at end of file diff --git a/src/test/java/lotto/ApplicationTest.java b/src/test/java/lotto/ApplicationTest.java index a15c7d1..d3f1135 100644 --- a/src/test/java/lotto/ApplicationTest.java +++ b/src/test/java/lotto/ApplicationTest.java @@ -1,13 +1,12 @@ package lotto; -import camp.nextstep.edu.missionutils.test.NsTest; -import org.junit.jupiter.api.Test; +import static org.assertj.core.api.Assertions.assertThat; +import static org.kokodak.test.Assertions.assertRandomUniqueNumbersInRangeTest; +import static org.kokodak.test.Assertions.assertSimpleTest; 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 org.junit.jupiter.api.Test; +import org.kokodak.test.NsTest; class ApplicationTest extends NsTest { private static final String ERROR_MESSAGE = "[ERROR]"; @@ -58,4 +57,41 @@ class ApplicationTest extends NsTest { public void runMain() { Application.main(new String[]{}); } -} + @Test + void 기능_테스트2등() { + assertRandomUniqueNumbersInRangeTest( + () -> { + run("1000", "1,2,3,4,5,7", "42"); + assertThat(output()).contains( + "1개를 구매했습니다.", + "[1, 2, 3, 4, 7, 42]", + "3개 일치 (5,000원) - 0개", + "4개 일치 (50,000원) - 0개", + "5개 일치 (1,500,000원) - 0개", + "5개 일치, 보너스 볼 일치 (30,000,000원) - 1개", + "6개 일치 (2,000,000,000원) - 0개", + "총 수익률은 3000000.0%입니다." + ); + }, + List.of(1, 2, 3, 4, 42, 7) + ); + }@Test + void 기능_테스트1등() { + assertRandomUniqueNumbersInRangeTest( + () -> { + run("1000", "1,2,3,4,5,6", "7"); + assertThat(output()).contains( + "1개를 구매했습니다.", + "[1, 2, 3, 4, 5, 6]", + "3개 일치 (5,000원) - 0개", + "4개 일치 (50,000원) - 0개", + "5개 일치 (1,500,000원) - 0개", + "5개 일치, 보너스 볼 일치 (30,000,000원) - 0개", + "6개 일치 (2,000,000,000원) - 1개", + "총 수익률은 200000000.0%입니다." + ); + }, + List.of(1, 2, 3, 4, 5,6) + ); + } +} \ No newline at end of file diff --git a/src/test/java/lotto/InputViewTest.java b/src/test/java/lotto/InputViewTest.java new file mode 100644 index 0000000..1eb6300 --- /dev/null +++ b/src/test/java/lotto/InputViewTest.java @@ -0,0 +1,114 @@ +package lotto; + +import lotto.util.ExceptionMessage; +import lotto.view.InputView; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.util.List; + +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +public class InputViewTest { + private InputView inputview= new InputView(); + @DisplayName("금액은 1000원가 아니면 예외가 발생한다. ") + @Test + void 천원단위검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("101".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + assertThatThrownBy(()-> inputview.readMoney()). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_MONEY_UNIT.getMessage()); + } + + @DisplayName("0원이면 예외가 발생한다. ") + @Test + void 빵원검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("0".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + assertThatThrownBy(()-> inputview.readMoney()). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.ZERO_EXCEPTION.getMessage()); + } + + @DisplayName("당첨번호가 정수인지 검증") + @Test + void 당첨번호정수검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("1,2,3,4,5,k".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + assertThatThrownBy(()-> inputview.readWinningNumbers()). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.NOT_INT.getMessage()); + } + + @DisplayName("당첨번호가 1~45인지 검증") + @Test + void 당첨번호범위검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("1,2,3,4,5,800".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + assertThatThrownBy(()-> inputview.readWinningNumbers()). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_LOTTO_NUMBER_RANGE.getMessage()); + } + + @DisplayName("당첨번호가 6개인지 검증") + @Test + void 당첨번호개수검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("1,2,3,4,5".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + assertThatThrownBy(()-> inputview.readWinningNumbers()). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_WINNING_SIZE.getMessage()); + in = new ByteArrayInputStream("1,2,3,4,5,6,7".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + assertThatThrownBy(()-> inputview.readWinningNumbers()). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_WINNING_SIZE.getMessage()); + } + @DisplayName("당첨번호중에 중복이 있는지 검증") + @Test + void 당첨번호중복검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("1,2,3,4,5,5".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + assertThatThrownBy(()-> inputview.readWinningNumbers()). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_WINNING_NUMBER_DUPLICATE.getMessage()); + } + @DisplayName("보너스번호 정수 검증") + @Test + void 보너스번호정수검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("1k".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + + assertThatThrownBy(()-> inputview.readBonusNumber(List.of(1, 2, 3, 4, 5, 6))). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.NOT_INT.getMessage()); + } + @DisplayName("보너스번호 중복 검증") + @Test + void 보너스번호중복검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("5".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + + assertThatThrownBy(()-> inputview.readBonusNumber(List.of(1, 2, 3, 4, 5, 6))). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_BONUS_NUM.getMessage()); + } + + @DisplayName("보너스번호 범위 검증") + @Test + void 보너스번호범위검증(){ + ByteArrayInputStream in = new ByteArrayInputStream("51".getBytes(StandardCharsets.UTF_8)); + System.setIn(in); + + assertThatThrownBy(()-> inputview.readBonusNumber(List.of(1, 2, 3, 4, 5, 6))). + isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_LOTTO_NUMBER_RANGE.getMessage()); + } + + + +} diff --git a/src/test/java/lotto/LottoTest.java b/src/test/java/lotto/LottoTest.java index 0f3af0f..d593834 100644 --- a/src/test/java/lotto/LottoTest.java +++ b/src/test/java/lotto/LottoTest.java @@ -1,5 +1,7 @@ package lotto; +import lotto.domain.Lotto; +import lotto.util.ExceptionMessage; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -23,5 +25,14 @@ void createLottoByDuplicatedNumber() { .isInstanceOf(IllegalArgumentException.class); } + // 아래에 추가 테스트 작성 가능 + @DisplayName("로또 번호에 범위가 넘어간 숫자가 있으면 예외가 발생한다.") + @Test + void 로또범위테스트() { + // TODO: 이 테스트가 통과할 수 있게 구현 코드 작성 + assertThatThrownBy(() -> new Lotto(List.of(1, 2, 3, 4, 5, 51))) + .isInstanceOf(IllegalArgumentException.class) + .hasMessageContaining(ExceptionMessage.INVALID_LOTTO_NUMBER_RANGE.getMessage()); + } }