https://devroach.tistory.com/52?category=1031971
앞서 설명한 테스트 더블에 대해서 어떤 종류가 있는지 조금 더 알아보자.
테스트 더블의 종류
테스트 더블은 아래와 같이 4가지 분류로 나뉜다.
테스트 스텁
테스트 스텁은 원래의 구현을 최대한 단순한 것으로 바꾸는 것이다.
우리가 만약에 서버에서 로깅을 하다가 실패하는 로그를 찍어야 된다고 해보자.
하지만 로깅 자체는 테스트 로직에는 영향을 주지 않아 독립시켜야 한다.
그럴땐 어떻게 해야할까? 한번 코드로 적어보자.
위의 코드를 한번 살펴보자.
Logger 를 Stub 한 모습인데 log 에서는 아무것도 하지 않는다.
또한 getLogLevel 에서는 WARN 이 하드코딩되어 배출된다.
이상하다고 느껴질 수 있는데 우리의 목표를 이룬셈이다.
우리가 하려는 테스트는 로깅 자체에서는 실패만 확인하면 되므로 영향을 딱히 주지 않는다.
그래서 로깅 테스트를 Stubbing 해서 더 테스트를 우리가 원하는 로직만 테스트 할 수 있도록 되었다.
가짜객체
가짜 객체는 Stub 에 비하면 정성이 들어간 객체이다.
음 내 생각엔 Stub 은 정말 아무것도 안하고 단순 값만 뱉어내는 그런 수준이다.
일단 백문이 불여일타 라고 코드를 먼져 한번 작성해보자.
유저를 저장소에서 가져오는 UserRepository 인터페이스이다.
우리가 할 테스트에서 UserRepository 는 반드시 데이터베이스에서 데이터를 가져온다.
라고 생각하고 Service Logic 을 테스트 할것이다.
왜냐하면 Service Logic 테스트가 알수없는 데이터 베이스 오류에 영향을 받는다면
이는 고립된 테스트가 아님을 의미하게 된다.
따라서 우리는 UserRepository 의 가짜 객체를 생성해야 한다.
우리는 이제 가짜 객체를 통해서 DB 에도 접근을 안해도 되므로 더 빠른 테스트가 가능해졌다.
테스트 스파이
테스트 스파이는 말그대로 잠입해서 정보를 캐내는 역할을 하는 녀석을 뜻한다.
만약 아래와 같은 클래스가 있다고 해보자
이렇게 됬을때 우리가 DLog 에 넘겨준 값을 DLogTarget 에 잘 넘어갔는지 확인하고 싶으면 어떻게 해야할까?
바로 Spy 객체를 생성해야 한다.
한번 코드로 작성해보자.
위의 코드를 한번보자
우리는 SpyTarget 을 만들어서 내부적으로 주입받은 값을 확인할 수 있도록 했다.
SpyTarget 은 이처럼 DLog 안에 잠입해서 정보를 추출해냈다.
Mock 객체
Mock 객체는 특수한 형태의 테스트 스파이 이다
Mock 객체는 특정 조건이 충족되면 원하는 결과값을 표출해준다.
예를 들어 아까 findById 에 123 을 넣으면 null 을 반환하고, 124 를 넣으면 User 를 반환하는 식이다.
Mock 객체에 대해서 좀 더 자세히 알기 위해서는 Mockito 와 같은 라이브러리를 써보는걸 추천한다.
용도에 맞는 테스트 더블을 선택하라
테스트를 많이 짜면 테스트 또한 코드로 유지보수 되어야할 대상이 된다.
그래서 어떤 테스트 더블을 선택하느냐가 중요할 수 있다.
그래서 필자가 써놓은 5가지 방법에 대해서 적어보려고 한다.
1. 두 객체간의 상호작용의 결과로 특정 메서드가 호출되었는지를 확인하기 위해서는 Mock 객체를 써야할 가능성이 높다.
2. Mock 객체를 사용했는데, 코드가 깔끔하지 않는다면 직접 Spy 객체를 작성하는것도 좋다.
3. 협력 객체는 자리만 지키면 되고, 협력 객체가 대상 객체에게 넘겨줄 응답도 테스트에서 통제할 수 있다면 Stub 이 정답이다.
4. 필요한 컴포넌트를 준비하지 못해 Stub 을 사용하고 있는데, 시나리오가 복잡해지거나 테스트코드가 복잡해 졌다면 가짜 객체가 정답이다.
또 다른 방법으로 Junit Recipes 의 저자 레인스버거가 말하는 방법은
"Stub 은 질문하고, Mock 은 행동한다"
위와 같은 방법을 잘 선택하여서 테스트 코드 또한 가독성이 좋게 리팩토링하거나 관리하여야 한다.
구현이 아니라 동작을 확인하라!
이건 테스트 관련해서 세미나를 들어보면 항상 나오는 말이다.
아래글에 더 정리가 잘되있으니 궁금하면 읽어보길 바란다.
https://devroach.tistory.com/35?category=1031971
종속객체를 주입할 수 있는 구조로 짜라
이것또한 테스트를 공부하다 보면 계속 느끼는 것인데
결국 테스트 더블을 하기 위해서 가짜 객체를 주입시키기 위해서는 DI 구조로 설계되어야 한다.
테스트 하기 쉽도록 코드를 짜는 것도 능력이다.
'Test' 카테고리의 다른 글
[TEST] When 에서 하나 이상의 메소드 실행 피하기 (1) | 2021.12.17 |
---|---|
테스트 더블 (0) | 2021.11.19 |
어떤 것이 좋은 테스트 코드인가? (0) | 2021.11.19 |
테스트를 어떻게 해야하는가? (0) | 2021.10.27 |