ewhk9887/korean_code_reviews_from_github huggingface dataset:
@@ -0,0 +1,7 @@
+package exception.utils;
+
+public class NoFileException extends Exception {
+    public NoFileException(String path) {
+        super(path + " 파일을 찾을 수 없습니다.");
+    }
+}

리뷰: NoFIleException 과 같은 경우에는 어떤 파일을 찾을 수 없는지 표시될 수 있게 개선되면 더 좋겠습니다.
@@ -0,0 +1,30 @@
+package controller;
+
+import exception.utils.NoFileException;
+import model.request.HttpRequest;
+import model.response.HttpResponse;
+
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class ViewController extends Controller {
+
+    {
+        setBasePath("");
+        putHandler("/js/.*", "GET", this::handleFile);
+        putHandler("/css/.*", "GET", this::handleFile);
+        putHandler("/fonts/.*", "GET", this::handleFile);
+        putHandler("/favicon.ico", "GET", this::handleFile);
+        putHandler("/index.html", "GET", this::handleView);
+        putHandler("/", "GET", this::handleView);
+    }
+
+    public void handleFile(HttpRequest request, HttpResponse response) throws NoFileException {
+        response.forward("./static", request.getPath());
+    }
+
+    public void handleView(HttpRequest request, HttpResponse response) throws NoFileException {
+        response.forward("./templates",
+                (request.getPath().equals("/") ? "/index.html" : request.getPath()));
+    }
+}

리뷰: ![image](https://user-images.githubusercontent.com/1266944/106766656-68cad300-667d-11eb-9e7b-52fffd02632d.png)

Fonts 파일이 로딩되지 않는 현상이 있습니다. 확인 부탁드려요 :smile
@@ -0,0 +1,45 @@
+package controller;
+
+import controller.handler.Handler;
+import exception.utils.NoFileException;
+import model.request.HttpRequest;
+import model.response.HttpResponse;
+import model.PathInfo;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+public abstract class Controller {
+    private static final Logger log = LoggerFactory.getLogger( Controller.class );
+    protected final Map<PathInfo, Handler> handlers = new HashMap<>();
+    protected String basePath = "";
+
+    public void putHandler(String path, String method, Handler handler) {
+        handlers.put(new PathInfo(basePath + path, method), handler);
+    }
+
+    public void setBasePath(String basePath) {
+        this.basePath = basePath;
+    }
+
+    public boolean hasSameBasePath(String path) {
+        return path.startsWith(basePath);
+    }
+
+    public boolean handle(HttpRequest request, HttpResponse response) throws NoFileException, IOException {
+        for (Map.Entry<PathInfo, Handler> entry : handlers.entrySet()) {
+            log.info("matching {} with controller {}", request.getPath(), entry.getKey().getPath());
+
+            if (request.getPath().matches(entry.getKey().getPath())) {
+                log.info("handling {} with controller {}", request.getPath(), entry.getKey().getPath());
+                entry.getValue().handle(request, response);
+                return true;
+            }
+        }
+        return false;
+    }
+}

리뷰: Handlers 가 순서를 기반으로 등록되어야 할 필요가 있다면 차후에 실수하기 쉬운 구조 입니다.
path 를 기반으로 동작할 handler 가 다른 방식으로 매칭될 수는 없을지 고민해봐주세요 😄
@@ -0,0 +1,85 @@
+package model.request;
+
+import utils.IOUtils;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public class HttpRequest {
+    private HttpRequestLine httpRequestLine;
+    private HttpRequestHeader httpRequestHeader;
+
+    private String body = "";
+
+    private HttpRequest(BufferedReader br) throws IOException {
+        String line = br.readLine();
+        httpRequestLine = new HttpRequestLine(line);
+        httpRequestHeader = new HttpRequestHeader(br);
+        setBody(br);
+    }
+
+    public static HttpRequest of(InputStream in) throws IOException {
+        return new HttpRequest(new BufferedReader(new InputStreamReader(in)));
+    }
+
+    private void setBody(BufferedReader br) throws IOException {
+        while(br.ready()){
+            body = IOUtils.readData(br, Integer.parseInt(getHeader("Content-Length")));
+        }
+    }
+
+    public String getBody() {
+        return body;
+    }
+
+    public Map<String, String> getParsedBody(){
+        Map<String, String> parsedBody = new HashMap<>();
+        String[] queryParams = body.split("&");
+        Arrays.stream(queryParams).forEach((param) -> {
+            String[] args = param.split("=", 2);
+            parsedBody.put(args[0].trim(), args[1].trim());
+        });
+        return parsedBody;
+    }
+
+    public String getCookie(String cookieParam){
+        Map<String, String> parsedCookie = new HashMap<>();
+        String cookieHeader = getHeader("Cookie");
+
+        String[] cookies = cookieHeader.split(";");
+        Arrays.stream(cookies).forEach((cookie) -> {
+           String[] args = cookie.split("=", 2);
+           parsedCookie.put(args[0].trim(), args[1].trim());
+        });
+        return parsedCookie.get(cookieParam);
+    }
+
+    public Map<String, String> getHeaderMap() {
+        return httpRequestHeader.getHeaderMap();
+    }
+
+    public String getHeader(String key){
+        return httpRequestHeader.getHeader(key);
+    }
+
+    public String getMethod() {
+        return httpRequestLine.getMethod();
+    }
+
+    public String getPath() {
+        return httpRequestLine.getPath();
+    }
+
+    public String getProtocol() {
+        return httpRequestLine.getProtocol();
+    }
+
+    public Map<String, String> getQueryParameterMap() {
+        return httpRequestLine.getQueryParameterMap();
+    }
+}

리뷰: InputStream 을 받아서 HttpRequest 인스턴스를 생성하는 static method 로 변경해보는건 어떨까요?
@@ -0,0 +1,12 @@
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  position: fixed;
+  width: calc(430px - 48px);
+  height: 64px;
+  padding: 0 24px;
+  background-color: black;
+  color: #fff;
+  z-index: 1000;
+}

리뷰: 피그마 시안 width가 430px이었고, 양 옆 padding이 24였어서 이런 calc 코드가 나왔습니다..
✋🏻보통 이렇게 처리하시는지, 혹은 더 유연한 방식이 있는지 궁금합니다.
@@ -4,13 +4,15 @@
   "version": "0.0.0",
   "type": "module",
   "scripts": {
-    "dev": "vite",
+    "dev": "vite --host",
     "build": "tsc && vite build",
     "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
     "preview": "vite preview",
     "test": "vitest"
   },
   "dependencies": {
+    "@jaymyong66/simple-modal": "^0.0.7",
+    "@tanstack/react-query": "^5.40.1",
     "react": "^18.2.0",
     "react-dom": "^18.2.0"
   },

리뷰: 굉장히 사소하지만 커밋 메시지 관련 리뷰 남겨봅니다..! 저는 패키지 관련 설치는 chore를 사용합니다..! 이게 완벽하게 정확한 지는 검증해보지 않았으나, 참고해보면 좋을 것 같아요!

[좋은 커밋 메시지 작성법](https://velog.io/@iamjm29/Git-%EC%A2%8B%EC%9D%80-%EC%BB%A4%EB%B0%8B-%EB%A9%94%EC%8B%9C%EC%A7%80-%EC%9E%91%EC%84%B1%EB%B2%95)

[AngularJS Commit Convention](https://gist.github.com/stephenparish/9941e89d80e2bc58a153)
@@ -0,0 +1,12 @@
+.header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  position: fixed;
+  width: calc(430px - 48px);
+  height: 64px;
+  padding: 0 24px;
+  background-color: black;
+  color: #fff;
+  z-index: 1000;
+}

리뷰: 대박 왜 이제 알았지..? 👍
@@ -0,0 +1,58 @@
+package chess.domain.command;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public enum Command {
+
+    START("start"),
+    END("end"),
+    MOVE("move"),
+    STATUS("status");
+
+    private static final Map<String, Command> COMMANDS = createCommands();
+
+    private static Map<String, Command> createCommands() {
+        Map<String, Command> commands = new HashMap<>();
+
+        Arrays.stream(values())
+                .forEach(command -> commands.put(command.command, command));
+
+        return commands;
+    }
+
+    private final String command;
+
+    Command(final String command) {
+        this.command = command;
+    }
+
+    public static Command of(final String command) {
+        Command foundCommand = COMMANDS.get(command);
+
+        if (foundCommand == null) {
+            throw new IllegalArgumentException("유효하지 않은 명령어입니다.");
+        }
+
+        return foundCommand;
+    }
+
+    public void validateInitialCommand() {
+        if (isStatus() || isMove()) {
+            throw new IllegalArgumentException(String.format("%s 또는 %s를 입력해주세요.", START.command, END.command));
+        }
+    }
+
+    public boolean isEnd() {
+        return this.equals(END);
+    }
+
+    public boolean isMove() {
+        return this.equals(MOVE);
+    }
+
+    public boolean isStatus() {
+        return this.equals(STATUS);
+    }
+}

리뷰: Command도 Enum으로 관리해보면 어떨까요? :)
@@ -0,0 +1,58 @@
+package chess.domain.command;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+public enum Command {
+
+    START("start"),
+    END("end"),
+    MOVE("move"),
+    STATUS("status");
+
+    private static final Map<String, Command> COMMANDS = createCommands();
+
+    private static Map<String, Command> createCommands() {
+        Map<String, Command> commands = new HashMap<>();
+
+        Arrays.stream(values())
+                .forEach(command -> commands.put(command.command, command));
+
+        return commands;
+    }
+
+    private final String command;
+
+    Command(final String command) {
+        this.command = command;
+    }
+
+    public static Command of(final String command) {
+        Command foundCommand = COMMANDS.get(command);
+
+        if (foundCommand == null) {
+            throw new IllegalArgumentException("유효하지 않은 명령어입니다.");
+        }
+
+        return foundCommand;
+    }
+
+    public void validateInitialCommand() {
+        if (isStatus() || isMove()) {
+            throw new IllegalArgumentException(String.format("%s 또는 %s를 입력해주세요.", START.command, END.command));
+        }
+    }
+
+    public boolean isEnd() {
+        return this.equals(END);
+    }
+
+    public boolean isMove() {
+        return this.equals(MOVE);
+    }
+
+    public boolean isStatus() {
+        return this.equals(STATUS);
+    }
+}

리뷰: 상수들이기 때문에 Enum으로 관리하는 편이 더 좋겠네요!
Enum 객체로 수정하였습니다 :)
@@ -0,0 +1,46 @@
+package lottodomain;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class LottoGame {
+    private static final int PRICE_PER_LOTTO = 1000;
+
+    private List<Lotto> allLotto;
+    private int numberOfAllLotto;
+
+    public LottoGame(int inputMoney, List<List<Integer>> manualLottoNos) {
+        numberOfAllLotto = inputMoney / PRICE_PER_LOTTO;
+        allLotto = issueLottos(manualLottoNos);
+    }
+
+    public LottoAnalyzer getLottoAnalyzer(WinningNos winningNos) {
+        return new LottoAnalyzer(allLotto, winningNos);
+    }
+
+    public List<Lotto> getAllLotto() {
+        return allLotto;
+    }
+
+    private List<Lotto> issueLottos(List<List<Integer>> manualLottoNos) {
+        List<Lotto> lottos = issueManualLottos(manualLottoNos);
+        lottos.addAll(issueAutoLottos(numberOfAllLotto - lottos.size()));
+        return lottos;
+    }
+
+    private List<Lotto> issueManualLottos(List<List<Integer>> manualLottoNos) {
+        List<Lotto> ManualLottos = new ArrayList<>();
+        for (int i = 0; i < manualLottoNos.size(); i++) {
+            ManualLottos.add(LottoGenerator.generateLottoWithNos(manualLottoNos.get(i)));
+        }
+        return ManualLottos;
+    }
+
+    private List<Lotto> issueAutoLottos(int numberOfAutoLottos) {
+        List<Lotto> autoLottos = new ArrayList<>();
+        for (int i = 0; i < numberOfAutoLottos; i++) {
+            autoLottos.add(LottoGenerator.generateAutoLotto());
+        }
+        return autoLottos;
+    }
+}

리뷰: 변수명이 대문자로 시작하네요 ~
@@ -0,0 +1,25 @@
+package lottodomain;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+public class LottoGenerator {
+    private static final List<Integer> LOTTO_NO_POOLS = IntStream.rangeClosed(1, 45).boxed().collect(Collectors.toList());
+    ;
+
+    public static Lotto generateLottoWithNos(List<Integer> lottoNos) {
+        return new Lotto(lottoNos);
+    }
+
+    public static Lotto generateAutoLotto() {
+        return generateLottoWithNos(getRandomNos());
+    }
+
+
+    private static List<Integer> getRandomNos() {
+        Collections.shuffle(LOTTO_NO_POOLS);
+        return LOTTO_NO_POOLS.subList(0, 6);
+    }
+}

리뷰: Lotto 에 factory method 을 추가하여 생성해보면 어떨까요?
ex> Lotto.ofAuto(), Lotto.ofManual("1,2,3,4,5,6)
@@ -0,0 +1,25 @@
+package lottodomain;
+
+public class LottoNo {
+    private Integer value;
+
+    public LottoNo(int number) {
+        value = number;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        LottoNo lottoNo = (LottoNo) o;
+        return value == lottoNo.value;
+    }
+}

리뷰: LottoNo 를 생성할 때 range 에 대한 조건을 검증하면 좀 더 의미 있는 wrapping class 가 되지 않을까요?
@@ -0,0 +1,25 @@
+package lottodomain;
+
+public class LottoNo {
+    private Integer value;
+
+    public LottoNo(int number) {
+        value = number;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        LottoNo lottoNo = (LottoNo) o;
+        return value == lottoNo.value;
+    }
+}

리뷰: 문제 : 
"모든 원시값과 문자열을 포장한다." 원칙에 따라 인스턴스를 생성하다보니 너무 많은 객체가 생성되고, GC가 되어 성능상 문제가 발생한다.
특히 로또 번호 하나까지 객체로 포장할 경우 생성되는 인스턴스의 수는 상당히 늘어나는 문제가 발생한다.

위와 같은 문제는 어떻게 해결할 수 있을까요? (키워드 : static, map)
@@ -0,0 +1,25 @@
+package lottodomain;
+
+public class LottoNo {
+    private Integer value;
+
+    public LottoNo(int number) {
+        value = number;
+    }
+
+    public Integer getValue() {
+        return value;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        LottoNo lottoNo = (LottoNo) o;
+        return value == lottoNo.value;
+    }
+}

리뷰: 불변의 값을 wrapping 한 클래스이므로 final int value; 로 선언해보면 어떨까요?
@@ -0,0 +1,49 @@
+package lottoview;
+
+import lottodomain.Lotto;
+import lottodomain.LottoAnalyzer;
+import lottodomain.LottoNo;
+import lottodomain.Rank;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+public class OutputView {
+    public static void showAllLottos(List<Lotto> allLotto, int numberOfManualLottos) {
+        int numberOfAutoLottos = allLotto.size() - numberOfManualLottos;
+        System.out.printf("수동으로 %d장, 자동으로 %d장을 구매했습니다.\n", numberOfManualLottos, numberOfAutoLottos);
+        allLotto.stream().forEach(lotto -> showLotto(lotto));
+    }
+
+    public static void showLotto(Lotto lotto) {
+        List<LottoNo> lottoNos = lotto.getLottoNos();
+        System.out.println(lottoNos.stream().map(LottoNo::getValue).map(number -> number.toString())
+                .collect(Collectors.joining(", ", "[", "]")));
+    }
+
+    public static void showAnalysis(LottoAnalyzer lottoAnalyzer) {
+        showWRanks(lottoAnalyzer);
+        showEarningRate(lottoAnalyzer.calculateEarningRate());
+    }
+
+    public static void showRankCount(Rank rank, int count) {
+        System.out.printf("%d개 일치 (%d원)- %d개\n", rank.getCountOfMatch(), rank.getWinningMoney(), count);
+    }
+
+    public static void showEarningRate(double earningRate) {
+        System.out.printf("총 수익률은 %.1f%%입니다.\n", earningRate);
+    }
+
+    private static void showWRanks(LottoAnalyzer lottoAnalyzer) {
+        System.out.println("당첨 통계");
+        System.out.println("---------");
+        List<Rank> prize = Stream.of(Rank.values()).collect(Collectors.toList());
+        prize.remove(Rank.MISS);
+        for (int i = prize.size() - 1; i >= 0; i--) {
+            int count = lottoAnalyzer.countRank(prize.get(i));
+            showRankCount(prize.get(i), count);
+        }
+    }
+}

리뷰: analyzer 가 outputview 에 와서 비즈니스 로직을 수행하고 있는데요 
게임의 결과를 담는 LottoResults(DTO) 클래스와 Lotto list 를 감싸는 Lottos 클래스를 만들어서 
outputview 에서 비즈니스 로직이 실행되지 않도록 변경해보면 어떨까요?
@@ -0,0 +1,63 @@
+package lottodomain;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class LottoAnalyzerTest {
+    private static final double DELTA = 1e-15;
+
+    private List<Lotto> lottos;
+    private LottoAnalyzer lottoAnalyzer;
+    private WinningNos winningNos;
+
+    @Before
+    public void setUp() throws Exception {
+        lottos = new ArrayList<>();
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 4, 5, 6))); // FIRST
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 4, 5, 7))); // SECOND
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 4, 5, 8))); // THIRD
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 4, 7, 8))); // FOURTH
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 7, 8, 9))); // FIFTH
+        lottos.add(new Lotto(Arrays.asList(1, 2, 7, 8, 9, 10))); // MISS
+        winningNos = new WinningNos(Arrays.asList(1, 2, 3, 4, 5, 6), 7);
+        lottoAnalyzer = new LottoAnalyzer(lottos, winningNos);
+    }
+
+    @Test
+    public void calculateRankOfLotto() {
+        List<Rank> ranks = Arrays.asList(Rank.values());
+        for (int i = 0; i < lottos.size(); i++) {
+            assertEquals(ranks.get(i), lottoAnalyzer.calculateRankOfLotto(lottos.get(i), winningNos));
+        }
+    }
+
+    @Test
+    public void calculateEarnedMoney() {
+        assertEquals(2031555000, lottoAnalyzer.calculateEarnedMoney());
+    }
+
+    @Test
+    public void calculateEarningRate() {
+        assertEquals(33859250.0, lottoAnalyzer.calculateEarningRate(), DELTA);
+    }
+
+    @Test
+    public void countRank() {
+        List<Rank> ranks = Arrays.asList(Rank.values());
+        for (int i = 0; i < ranks.size(); i++) {
+            assertEquals(1, lottoAnalyzer.countRank(ranks.get(i)));
+        }
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        lottos = null;
+    }
+}
\ No newline at end of file

리뷰: 좋은 유닛테스트 작성법에는 F.I.R.S.T 라는 원칙이 있는데요
https://coding-start.tistory.com/261
첨부하고 갑니다 ~
@@ -0,0 +1,47 @@
+package lottodomain;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import static org.junit.Assert.*;
+
+public class LottoGameTest {
+    private LottoGame lottoGame;
+    List<List<Integer>> manualLottoNumbers;
+
+    private void assertArrayEquals(List<Lotto> expectedLottos, List<Lotto> subList) {
+        for (int i = 0; i < expectedLottos.size(); i++) {
+            assertEquals(expectedLottos.get(i), subList.get(i));
+        }
+    }
+
+    @Before
+    public void setUp() throws Exception {
+        manualLottoNumbers = new ArrayList<>();
+        manualLottoNumbers.add(Arrays.asList(1, 2, 3, 4, 5, 6));
+        manualLottoNumbers.add(Arrays.asList(1, 4, 11, 15, 19, 23));
+        manualLottoNumbers.add(Arrays.asList(4, 10, 17, 25, 34, 42));
+    }
+
+    @Test
+    public void setManualLottos() {
+        lottoGame = new LottoGame(10000, manualLottoNumbers);
+        assertEquals(10, lottoGame.getAllLotto().size());
+
+        List<Lotto> expectedLottos = manualLottoNumbers.stream().map(numbers -> LottoGenerator.generateLottoWithNos(numbers))
+                .collect(Collectors.toList());
+        assertArrayEquals(expectedLottos, lottoGame.getAllLotto().subList(0, 3));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        lottoGame = null;
+        manualLottoNumbers = null;
+    }
+}
\ No newline at end of file

리뷰: private method 는 public 보다 아래에 위치시켜주는게 가독성에 좋습니다 ~
@@ -0,0 +1,50 @@
+package lottodomain;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class WinningNosTest {
+    private WinningNos winningNos;
+
+    @Before
+    public void setUp() throws Exception {
+        winningNos = new WinningNos(Arrays.asList(1, 2, 3, 4, 5, 6), 7);
+    }
+
+    @Test
+    public void countMatchOf() {
+        List<Lotto> lottos = new ArrayList<>();
+        lottos.add(new Lotto(Arrays.asList(8, 9, 10, 11, 12, 13)));
+        lottos.add(new Lotto(Arrays.asList(1, 8, 9, 10, 11, 12)));
+        lottos.add(new Lotto(Arrays.asList(1, 2, 9, 10, 11, 12)));
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 10, 11, 12)));
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 4, 11, 12)));
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 4, 5, 12)));
+        lottos.add(new Lotto(Arrays.asList(1, 2, 3, 4, 5, 6)));
+
+        for (int i = 0; i < lottos.size(); i++) {
+            assertEquals(i, winningNos.countMatchOf(lottos.get(i)));
+        }
+    }
+
+    @Test
+    public void isBonus() {
+        Lotto trueLotto = new Lotto(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
+        Lotto falseLotto = new Lotto(Arrays.asList(1, 2, 3, 4, 5, 6, 8));
+
+        assertTrue(winningNos.isBonus(trueLotto));
+        assertFalse(winningNos.isBonus(falseLotto));
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        winningNos = null;
+    }
+}
\ No newline at end of file

리뷰: 전체적으로 코드에 비해 테스트 쪽이 조금 아쉬워서
시간이 되신다면 TDD 방법론을 통해 로또나 레이싱 게임을 다시 구현해보는 것도 많이 도움이 되실 것 같습니다