study/JUnit

[sailor-moon] 2024.09.27_JUnit : 가위바위보 입력 테스트

듀2 2024. 9. 29. 23:42

5. 가위바위보 입력테스트

 

* 코드 작성 전 테스트 조건

  1. 입력값이가위또는바위또는인지 확인
  2. 출력값이 입력값에 따라 이기는 경우인지 확인

 

* 작성 코드

package jh.day0927;

import java.util.InputMismatchException;
import java.util.Scanner;

public class Rsp {

    public String playRsp() {
        String output = null;
//        try {
            Scanner scanner = new Scanner(System.in);
            String input = scanner.nextLine();

            vaildInput(input);

            switch (input) {
                case "가위":
                    output = "바위";
                    break;
                case "바위":
                    output = "보";
                    break;
                case "보":
                    output = "가위";
                    break;
            } // end case
//        } catch(InputMismatchException e) {
//            playRsp();
//        } // end catch

        return output;
    } // playRsp

    public void vaildInput(String input) {
        if(!("가위".equals(input) || "바위".equals(input) || "보".equals(input))) {
            throw new InputMismatchException("가위/바위/보 중 하나만 입력 가능합니다.");
        } // end if
    } // validInput

} // class

 

 

* 테스트 코드

package jh.day0927;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvSource;
import org.junit.jupiter.params.provider.ValueSource;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.InputMismatchException;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;

@DisplayName("가위바위보 입출력 테스트")
public class RspTest {

    private Rsp rsp;

    @BeforeEach
    void createInstance() {
        rsp = new Rsp();
    } // createInstance

    public static InputStream generateInput(String input) {
        return new ByteArrayInputStream(input.getBytes());
    } // generateInput

    @ParameterizedTest
    @DisplayName("입력 예외 테스트")
    @ValueSource(strings = {"가위아님", "바위아님", "보아님"})
    void testInputException(String input) {
        InputStream inputStream = generateInput(input);
        System.setIn(inputStream);

        assertThatThrownBy(() -> rsp.playRsp()).isInstanceOf(InputMismatchException.class)
                .hasMessage("가위/바위/보 중 하나만 입력 가능합니다.");
    } // testInput

    @ParameterizedTest
    @DisplayName("아웃풋 테스트")
    @CsvSource(value = {"가위, 바위", "바위, 보", "보, 가위"})
    void testOutput(String input, String output) {
        InputStream inputStream = generateInput(input);
        System.setIn(inputStream);

        assertThat(rsp.playRsp()).isEqualTo(output);
    } // testOutput

} // class

 

* 입력값 테스트

- JUnit에서는 콘솔이 없으므로 System.in 대신 넣어줄 InputStream을 만들어주고, System.setIn을 통해 InputStream으로 입력값을 세팅한다.

- 출처 : https://sakjung.tistory.com/33

 

System.in과 System.out에 대한 테스트

우테코 자동차 경주 콘솔게임을 구현하면서 특히 단위 테스트 작성 연습에 집중했다. 이제 어느정도 단위 테스트에 대해 자신감이 차올랐을 때 문득 궁금한 점이 생겼다. System.in과 System.out 관련

sakjung.tistory.com

 

단순히 구현 코드를 실행시킬 때에는 사용자가 입력값을 입력하기만 하면 되었는데, JUnit에서 테스트할 때에 입력값을 어떻게 넣어줘야할지 생각해보는 시간이 되었다.

 

처음에는 try ~ catch 구문을 통해 예외를 처리했는데, 이렇게 처리하다보니 입력 예외에 대한 테스트가 불가하여 input을 검증하는 method를 만들고, 예외를 던져 테스트해주었다.
try ~ catch 구문을 통해 스스로를 재귀호출하여 예외가 터졌을 때 재입력을 받게 하고 싶었는데 테스트에서 계속 오류가 났다. 이 부분의 해결책을 추가로 더 고민해보아야 한다.
728x90