콘텐츠로 이동

2021 04 30

2021-04-30

Mocking

  • 참고: https://jojoldu.tistory.com/226
  • 문제점 - 통합 테스트 (하나의 Service 메서드 단위로 테스트) 진행 - 여러 레파지토리, 비즈니스 로직이 함께 있어 애로사항 많이 발생 - 불필요한 데이터 생성 - 테스트 범위 넓어져 - 피드백 slow - 상황 설정이 너무 장황함 - GIVEN이 너무 많아져서, when then에 집중 X - 실제 테스트 대상과는 무관한 객체와 필드가 너무 많음 - 하나의 테스트를 위해 필요한 주변 코드가 너무 많다!
  • 해결 방법 - 테스트 코드를 주변 코드와 격리해야함 - "테스트 더블": 목적에 따라 비슷한 듯 하면서도 다른 객체를 사용하는 것 - 테스트 대상 코드 격리 - 테스트 속도 개선 - 예측 불가능한 실행 요소 제거 - 특수 상황 테스트 가능 - 감춰진 정보 확인 가능
  • @MockBean - 참고: https://github.com/mockito/mockito/wiki/Mockito-features-in-Korean - 기존에 사용되던 Bean의 껍데기만 가져오고, 내부의 구현 부분은 모두 사용자에게 위임 - 해당 Bean으 어떤 메서드가 어떤 값이 입력되면 어떤 값이 리턴될지는 개발자가 조작 가능!!!! - 다음과 같이 chessService의 해당 로직의 참 조건을 지정해줘서, chessService 로직에 의존하는 Controller 테스트를 할 수 있었다!
    @MockBean
    private ChessService chessService;
    
    @Test
    void postLogin() throws Exception {
        Mockito.when(chessService.validateUser("test", "test")).thenReturn(true);
        mockMvc.perform(post("/login")
                .contentType(MediaType.APPLICATION_JSON)
                .content("{\"id\" : \"" + "test" + "\"" + ", " +
                        "\"password\" : \"" + "test" + "\"" +
                        "}"))
                .andExpect(status().isOk());
    }
    

토비의 스프링 1주차

  • 인상깊던 구절 - 객체지향 프로그래밍이 제공하는 폭넓은 혜택을 누릴 수 있도록 기본으로 돌아가자는 것이 스프링의 핵심 철학이다 - 객체를 설계할 때 가장 염두에 둬야 할 사항은 바로 미래의 변화를 어떻게 대비할 것인가이다. - 자유롭고 편리하게 변경, 발전, 확장시킬 수 있다는데 의미가 있다. - 관심이 같은 것끼리는 하나의 객체 안으로 또는 친한 객체로 모이게 하고, 관심이 다른 것은 가능한 한 따로 떨어져서 서로 영향을 주지 않도록 분리하는 것 - 이런 문제의 근본적인 원인은 UserDao가 바뀔 수 있는 정보, 즉 DB 커넥션을 가져오는 클래스에 대해 너무 많이 알고 있기 때문이다 - 따라서 UserDao는 DB 커넥션을 가져오는 구체적인 방법에 종속되어 버린다 - 가장 좋은 해결책은 두 개의 클래스가 서로 긴밀하게 연결되어 있지 않도록 중간에 추상적인 느슨한 연결고리를 만들어 주는 것 - 클래스 사이에 관계가 만들어진다는 것은, 클래스가 아니라, 오브젝트와 오브젝트 사이의 관계를 설정해 줘야 한다는 것 - 오브젝트 사이의 관계가 만들어질라면 만들어진 오브젝트가 있어야 함 - 직접 오브젝트 만드는 법도 있지만, - 외부에서 만들어 준 것을 가져오는 방법도 있다! - 단지 오브젝트 사이에 다이내믹한 관계(런타임 관계)가 만들어 지는 것 - 팩토리: 객체의 생성 방법을 결정하고 그렇게 만들어진 오브젝트를 돌려주는 것 - 오브젝트 "생성"과 오브젝트 "사용"의 역할/책임 분리!
  • 디자인 패턴 - 템플릿 메서드 패턴 - 상속을 통해 슈퍼클래스의 기능을 확장할 때 사용 - 변하지 않는 기능 -> 슈퍼클래스 - 자주 변경되며 확장할 기능 -> 서브클래스 - 서브클래스에서 추상 메서드 / protected 메서드를 오버라이딩 하여 필요에 맞게 사용 - 팩토리 메서드 패턴 - 서브 클래스에서 오브젝트 생성 방법과 클래스를 결정할 수 있도록 미리 메서드를 정의했음 - 이 방식을 통해 오브젝트 생성 방법을 슈퍼클래스의 코드에서 독립 시키는 것
  • 제어의 역전 - 모든 제어권한을 다른 대상에게 위임 - 오브젝트가 자신이 사용할 오브젝트 스스로 선택 X, 생성 X - 자신도 어디서 어떻게 사용되는지 모름 - 기능만 구현해 놓으면, 필요한 클래스에서 호출해서 사용 - 실습에서 관심 분리, 책임 나누고, 확장 가능한 구조로 만들기 위해 "팩토리" 만든 것이 제어의 역전의 예시 - Spring은 IoC를 극한으로 적용하고 있는 프레임워크!

서버 진단하기

  • OS 공부하는 이유 - 우리의 코드는 서버에 배포된 후 빌드 - HDD 등 저장장치에 있는 프로그램들이 데이터가 메모리에 적재되고 스케줄러에 의해 CPU에서 연산 - 안정적으로 서비스 운영하려면 프로그램 실행 환경 학습할 필요 있음
  • 어떤 단계로 진단하는가? - 서버 장애의 종류 - hang이 걸린다? - 애플리케이션 응답 없음 - 여러가지 상황에 예외 발생해 동작 X - 점점 느려짐 - 특정 시간대/사용자/기능 등 문제 발생 - 전후 상황 파악하고 원인 분석해보자!
  • stat 형태 - 요약 / 이벤트 기록 / 스냅샷의 형태로 남김 - 요약 - sar, vmstat 등 "단위시간 정보"의 합계나 평균 보여줌 - 대략적인 상태 조사 - CPU 사용률 - I/O 평균 응답 - 이벤트 기록 - 패킷 캡쳐, 시스템 콜 기록 등 "순차적으로 이벤트 기록" - 문제 상황 재현등 상세한 내용 조사에 유리 - 스냅샷 - ps, top 등 순간의 상태를 기록해 문제 파악
  • USE 방법론 - Utilization: 얼만큼 자원 썼는가? - CPU utilization, Available memory, RX/TX 패킷량, Disk 사용률, IOPS 등을 확인 - vmstat 명령어로 OS 커널에서 취득할 수 있는 정보 확인 - si(swap-in), so(swap-out), us(user-time), sy(system-time), id(idle), wa(wait-i/o), st(stolen time 하이퍼바이저가 가상 CPU 서비스 하는 동안 실제 CPU 차지한 시간) - iostat 명령어로 OS 커널에서 취득한 디스크 사용률 - free 명령어로 메모리 사용량 확인 가능 - top: 서버 리소스 전반 확인 가능 - VIRT: 프로세스가 확보한 가상 메모리 영역 크기 - RES: 실제 물리 메모리 영역 크기 - SWAP이 발생한다는 것은 물리 메모리가 부족하다는 증거이기에, RES의 크기가 큰 프로세스 없나 확인해볼 것 - Saturation: 얼마나 많은 부하가 몰리는가? - Error: 에러가 발생했는가? - 에러 발생 로그를 확인해보자 > $ tail -f /var/log/syslog
      - 로그의 종류
          - 서버에서 남기는 시스템 로그 (var/log/syslog)
          - 애플리케이션 로그