본문 바로가기

우아한테크코스

[우테코 프리코스] 2주차

AssertJ
 
  • library import 
import static org.assertj.core.api.Assertions.*;
  • 사용법 예시

1) object assertion
either to determine equality of two objects or to examine the fields of an object.

public class Dog { 
 private String name; 
 private Float weight; 
  // standard getters and setters
}
Dog fido = new Dog("Fido", 5.25);
Dog fidosClone = new Dog("Fido", 5.25);
assertThat(fido).isEqualTo(fidosClone); 
assertThat(fido).isEqualToComparingFieldByFieldRecursively(fidosClone);

2) Boolean Assertions

assertThat("".isEmpty()).isTrue();

3) Iterable/Array Assertions

List<String> list = Arrays.asList("1", "2", "3");

assertThat(list).contains("1");
assertThat(list).isNotEmpty();
assertThat(list).startsWith("1");
assertThat(list)
  .isNotEmpty()
  .contains("1")
  .doesNotContainNull()
  .containsSequence("2", "3");

4) character Assertions

assertThat(someCharacter)
 .isNotEqualTo('a')
 .inUnicode()
 .isGreaterThanOrEqualTo('b')
 .isLowerCase();

5) class Assertions

assertThat(Runnable.class).isInterface();
assertThat(Exception.class).isAssignableFrom(NoSuchElementException.class);

6) file Assertions

assertThat(someFile)
  .exists()
  .isFile()
  .canRead()
  .canWrite();

7) throwable Assertions

assertThat(ex).hasNoCause().hasMessageEndingWith("c");
 assertThatThrownBy(() -> input.charAt(5))
                .isInstanceOf(StringIndexOutOfBoundsException.class)
                .hasMessageContaining("String index out of range: 5");

JUnit5

https://donghyeon.dev/junit/2021/04/11/JUnit5-완벽-가이드/

java style guide 따르기

C언어를 규칙에 맞게 쓰는 거에 익숙해서 이건 딱히 어려운게 없었다.
하나 특이한 점이 있었다면 if , for 문 뒤에 한 줄이라도 중괄호를 쳐야 하는 것. 이유는 코드 수정이 있을 때 한줄을 더 추가해야되면 들어가는 중괄호도 변경사항이 되기 때문에 처음부터 중괄호를 쳐두는게 낫다.

commit convention

feat (feature)
fix (bug fix)
docs (documentation)
style (formatting, missing semi colons, …)
refactor
test (when adding missing tests)
chore (maintain)

문법 익히기

  • parseInt()의 기능은 String타입의 숫자를 int타입으로 변환
  • throw new IllegalArgumentException
  • 접근 제어자 잘 사용하기
  • 객체 지향적으로 코드 짜려는 노력하기
  • 다음주는 stream 공부 더 해보기

기능 목록 docs 에 작성 후 작성한 목록에 따라 커밋

처음엔 docs 랑 코드랑 같이 커밋하는게 귀찮았는데 하다보니 습관화 되었다. 나중에 커밋 change 이력볼때 기능 목록이랑 같이 보이는게 확실히 이해하기 편하다. 하나씩 체크할때마다 퀘스트 완료하는 느낌도 들어서 좋았다.

자바 라이브러리 사용

build.gradle
dependencies는 의존성을 관리하고 설정하는 프로퍼티입니다. 여기에 필요한 라이브러리 등의 정보를 기술하면 그 라이브러리를 참조할 수 있게 됩니다.

  • 자바 파일에서 라이브러리를 import하고, 클래스나 메소드에 Go to / Declaration or Usages 를 사용하면 클래스나 메소드의 내부를 볼 수 있다.

어려웠던 점

  • 기능 구현 하면서 클래스 별로 메소드 만들어뒀는데 전체 로직에 맞게 돌아가게끔 합치는게 힘들었다. 접근제어자를 아직 숙지를 잘 못해서 클래스 내 메소드나 변수를 다른 클래스에서 사용해야 할때 에러가 많이 발생했다. static 선언 안하면 인스턴스 생성해서 불러야 하는데 어떨 때 static 선언해서 바로 메소드 호출하는 게 나은지 아니면 인스턴스 생성해서 호출하는게 나은지 구분이 잘 안간다 
  • 패키지를 어떻게 묶어야 하는지 기준이 잘 안선다. 우선 이번 과제는 클래스 별로 파일은 다 분리했고 모든 클래스가 다 baseball 게임 구현에 필요한 거여서 패키지는 다 동일하게 baseball 로 묶었다. 
  • 기능별로 테스트 하려고 보니까 문제점이 보였다
    우선 input 의 에러를 판단하는 input length check, input number range check, input number difference check 메소드를 따로 만들고 유저의 입력을 받는 getinputnumber 메소드에서 입력을 받고 에러 판단 3개 메소드를 호출하는 식으로 구현했었다. 그러고 보니 테스트를 진행할때 3개 메소드 각각을 테스트 하는 건 되는데 3개를 동시에 테스트해볼 수 가 없었다. 그리고 각각 테스트할때도 매개변수 타입이 다 달라서 테스트 코드 작성하기가 너무 불편했다.
 static List<Integer> getInputNumber() {
        System.out.print("숫자를 입력해주세요 : ");
        String input = Console.readLine();
        checkInputLength(input);
        checkNumberRange(input);
        List<Integer> inputNum = new ArrayList<>();
        for (int idx = 0; idx < INPUT_LENGTH; idx++) {
            inputNum.add(input.charAt(idx) - '0');
        }
        checkNumberDifference(inputNum);
        return inputNum;
    }

우선 string 으로 매개변수 받던 것 다 list 형으로 통일해주고

 public User(List<Integer> values){
        checkInputLength(values);
        checkNumberRange(values);
        checkNumberDifference(values);
        this.values = values;
    }

    public User(){
        values = getInputNumber();
        checkInputLength(values);
        checkNumberRange(values);
        checkNumberDifference(values);
    }

코드에서 사용할때는 매개변수 없는 아래, 테스트 시에는 위를 사용했는데 이렇게 하는게 맞나 모르겠다

  • computer 가 만드는 value 설정, user 가 넣는 input 설정 해서 에러 발생하나 확인하는 코드
  @Test
    void 종료코드_예외확인() {
        assertRandomNumberInRangeTest(
                () -> {
                    assertThatThrownBy(() -> {
                        run("2466", "135");
                    }).isInstanceOf(IllegalArgumentException.class);
                },
                1, 3, 5
        );
    }
  • 테스트를 기능별로 잘 진행하려면 객체지향적으로 코드를 짜야한다는 걸 여실히 느꼈던 주차였다