목 오브젝트(mock object)의 이해

37
목 목목목목 (Mock Object) 목 목목 2016.01.05 목목목

Upload: yong-hoon-kim

Post on 16-Apr-2017

5.218 views

Category:

Software


0 download

TRANSCRIPT

Page 1: 목 오브젝트(Mock Object)의 이해

목 오브젝트 (Mock Object) 의 이해

2016.01.05 김용훈

Page 2: 목 오브젝트(Mock Object)의 이해

목 차

1. 예제 프로젝트 ( 책 가격 계산기 ) 개요

2. 설계 : 전체 흐름 도식화 및 객체모델링

3. 구현 : 목 오브젝트를 이용한 유닛테스트 만들기

4. 테스트더블 (Test Double)

5. 정리

Page 3: 목 오브젝트(Mock Object)의 이해

최초 요구사항

(1) 결제시 사용자가 가지고 있는 포인트를 쓸 수 있다 . 포인트를 쓰면 쓴 포인트만큼 책 가격이 할인되어야 한다 . 

(2) 사용자는 쿠폰을 여러개 가질 수 있고 , 쿠폰별로 책의 카테고리와 매칭 여부에 따라 유효여부를 알 수 있는 기능이 있다 .

(3) 결제수단은 “카드 /계좌이체”가 있고 , “ 특정카드”로 결제시 할인이 적용되어 책 가격이 계산되어야 한다 . 

1. 예제 프로젝트 개요

Page 4: 목 오브젝트(Mock Object)의 이해

개발시 제약사항

(1) 유저정보를 가져오려면 회원팀에서 제공하는 인터페이스를

이용해야 하지만 아직 구현은 되지 않고 인터페이스만 전달된 상태이다

(2) 책과 카테고리 정보는 각각 도서팀과 전시기획팀에서 제공한 인터페이스를 이용해야 하지만 아직 구현은 되지 않고 인터페이스만 전달된 상태이다

(3) 결제수단은 외부 페이솔루션 ( 이니시스같은 ) 을 쓰기로 했고 ,

솔루션의 결제모듈은 커스터마이징이 필요하며 , 현재는 인터페이스만 제공된 상태이다 .

1. 예제 프로젝트 개요

Page 5: 목 오브젝트(Mock Object)의 이해

대략 그려본 객체간의 관계2. 설계

Page 6: 목 오브젝트(Mock Object)의 이해

2. 설계

전체 책 가격 계산과정 도식화

Page 7: 목 오브젝트(Mock Object)의 이해

객체 모델링 1

(1) 결제시 사용자가 가지고 있는 포인트를 쓸 수 있다 . 포인트를 쓰면 쓴 포인트만큼 책  가격이 할인되어야 한다

(2) 사용자는 쿠폰을 여러개 가질 수 있고 , 쿠폰별로 책의 카테고리와 매칭 여부에 따라 유효여부를 알 수 있는 기능이 있다 .

(3) 결제수단은 “카드 /계좌이체” 가 있고 , “ 특정카드” 로 결제시 할인이 적용되어 책 가격이 계산되어야 한다 

2. 설계

Page 8: 목 오브젝트(Mock Object)의 이해

객체 모델링 2

 

2. 설계

Page 9: 목 오브젝트(Mock Object)의 이해

최종결과물

 

2. 설계

Page 10: 목 오브젝트(Mock Object)의 이해

이제 구현을 시작해볼까 ?3. 구현

(1) 대략적으로 설계를 해봤으니 이제 구현을 해볼까 ? 

(2) 그런데 회원팀 , 도서팀 , 전시기획팀에서 아직 인터페이스만 전달하고 구현체는 없는데 난 로직을 어떻게 만들지 ?

(3) 그리고 외부페이 솔루션 업체에서 완성된 연동가이드를 일주일후에나 준다고 하는데 ... 그럼 난 일주일동안 뭐하지 ?

Page 11: 목 오브젝트(Mock Object)의 이해

3. 구현

이미지 출처 : http://visioneer4.tistory.com/292

Page 12: 목 오브젝트(Mock Object)의 이해

문제의 핵심은 ?3. 구현

(1) 나의 관심사는 책의 가격을 계산하는 로직을 만드는 것이다 .

(2) 하지만 , 내가 만드는 로직에는 의존하는 UserService, BookService, PaymentService, CategoryService 등의 협력객체가 필요하다

(3) 문제는 테스트대상코드인 책 가격계산기 객체가 의존하는 협력객체들의 실질적인 구현체가 없다는 것이다 !

3. 구현

Page 13: 목 오브젝트(Mock Object)의 이해

문제의 핵심은 ?

 

3. 구현

Page 14: 목 오브젝트(Mock Object)의 이해

목 오브젝트 (Mock Object) 활용3. 구현

(1) 진짜 객체를 만들 수 없는 상황이라면 이것을 돌파하기 위한 방법을 찾아야 한다

(2) 진짜처럼 행동하는 가짜 객체를 만들어보자

(3) 목 오브젝트 (Mock Object) 란 실제 모듈과 비슷하게 보이도록 만든 가짜 객체이다 .

Page 15: 목 오브젝트(Mock Object)의 이해

목 오브젝트 활용

 

3. 구현

Page 16: 목 오브젝트(Mock Object)의 이해

목 오브젝트 생성 및 주입

 

3. 구현

목 오브젝트 생성

Setter 메서드로 의존객체 주입 ( DI)branch : develop_v0.1

Page 17: 목 오브젝트(Mock Object)의 이해

목 오브젝트 가짜 구현 1

3. 구현

branch : develop_v0.1

Page 18: 목 오브젝트(Mock Object)의 이해

목 오브젝트 가짜 구현 2

3. 구현

branch : develop_v0.1

Page 19: 목 오브젝트(Mock Object)의 이해

목 오브젝트 가짜 구현 3

3. 구현

branch : develop_v0.1

Page 20: 목 오브젝트(Mock Object)의 이해

객체의 기능도 실제로 구현

3. 구현

쿠폰이 가지고 있는 카테고리와 살 책의 카테고리가 같은지 여부를 확인하는 기능을 실제로 구현함

branch : develop_v0.1

Page 21: 목 오브젝트(Mock Object)의 이해

테스트코드 결과물3. 구현

branch : develop_v0.1

요구된 최소 기능만테스트코드로 검증 !

Page 22: 목 오브젝트(Mock Object)의 이해

리팩토링 (Refactoring) 진행 1

3. 구현

branch : develop_v0.2

테스트코드마다 중복실행되는 목 오브젝트 생성과 주입부분을 setUp() 메서드로 빼냄

Page 23: 목 오브젝트(Mock Object)의 이해

리팩토링 (Refactoring) 진행 23. 구현

branch : develop_v0.2

Page 24: 목 오브젝트(Mock Object)의 이해

2. 설계

최초 구현 변경

branch : develop_v0.2

Page 25: 목 오브젝트(Mock Object)의 이해

2. 설계

최초 구현 변경

branch : develop_v0.2

Page 26: 목 오브젝트(Mock Object)의 이해

Junit + Mockito vs Spock 3. 구현

branch : develop_v0.3

Page 27: 목 오브젝트(Mock Object)의 이해

3. 구현

branch : develop_v0.3

Junit + Mockito vs Spock

Page 28: 목 오브젝트(Mock Object)의 이해

Junit + Mockito vs Spock 3. 구현

branch : develop_v0.3

Page 29: 목 오브젝트(Mock Object)의 이해

테스트 더블 (Test Double) 어원4. 테스트 더블

(1) “xUnit Test Patterns” 의 저자 제라드 메스자로스가 만들어 냄

(2) “ 대역 , 스턴트맨”을 나타나는 스턴트 더블 (Stunt Double) 에서 차용

(3) 오리지널 객체로 테스트를 진행하기 어려울 경우 , 이를 대신해 테스트를 진행할 수 있도록 만들어주는 객체임

Page 30: 목 오브젝트(Mock Object)의 이해

테스트 더블 (Test Double) 분류4. 테스트 더블

(1) 더미객체 (Dummy Object) : 인스턴스화될 수 있는 수준으로만 구현한 객체 . 껍데기

(2) 테스트 스텁 (Test Stub) : 더미 객체가 실제로 동작하는 것처럼 보이게 만들어 놓은 객체

(3) 페이크 객체 (Fake Object) : 여러 인스턴스 대표 , 또는 좀 더 복잡한 구현이 들어간 객체

(4) 테스트 스파이 (Test Spy) : 자신의 기능 외 메서드호출등의 기록정보를 알려주는 객체

(5) 목 오브젝트 (Mock Object) : 행위를 검증하기 위해 사용되는 객체

이미지 출처 : http://xunitpatterns.com/Test%20Double.html

Page 31: 목 오브젝트(Mock Object)의 이해

테스트더블과 목 오브젝트4. 테스트 더블

(1) 제라드가 분류한 목 오브젝트 : “ 행위 기반 테스트를 위해 사용되는 객체”

(2) 실제로 목 오브젝트는 넓은 의미의 “가상 임시 구현체” 의 의미로 사용되는 경우가 많음

(3) Mocking 은 테스트 더블 객체를 만드는 것을 의미 ( 행위 기반 테스트 객체 아님 )

(4) Mock 프레임워크 자체도 테스트 더블 전체 분류에 걸쳐 여러 의미로 사용

이미지 출처 : http://stackoverflow.com/a/9016164/1072651

Page 32: 목 오브젝트(Mock Object)의 이해

예제 프로젝트에서 본 테스트 더블4. 테스트 더블

Dummy Object

Test Stub

Test Spy

Page 33: 목 오브젝트(Mock Object)의 이해

예제 프로젝트에서 본 테스트 더블4. 테스트 더블

Fake Object

Mock Object

Page 34: 목 오브젝트(Mock Object)의 이해

Mock Object 가 필요한 시점5. 정리

(1) 테스트 대상 코드와 협력하는 객체와의 “ ”의존 을 제거 : 예제 프로젝트에선 아직 구현되지 않아 전달받지 못한 회원 , 책 , 카테고리정보 , 외부페이 솔루션 구현체 등이 이에 해당

(2) 예측 불가능한 요소를 제거 : 시간별 테스트 혹은 특정시점에 네트워크를 끊는 등의 테스트가 필요할 경우

(3) 테스트 속도 개선 : 예제 프로젝트에선 외부페이 솔루션과 연동하여 결제를 하는 액션이 실제로 오래 걸릴 수 있다 . 이를 신뢰성 높은 목 오브젝트로 대체해 테스트 할 수 있다

Page 35: 목 오브젝트(Mock Object)의 이해

핵심사항 요약

5. 정리

(1) 목 오브젝트 (Mock Object) 는 실제 객체를 흉내내 대신하기 위한 모조품 , 임시 가상 구현체이다

(2) 목 오브젝트는 협력객체와의 의존을 단절시킴으로써 , 내가 구현할 비지니스 로직에 집중할 수 있도록 만들어준다 .

(3) 제라드는 테스트가 어려운 경우 이를 도와주는 객체를 일컬어 “ 테스트 더블”이라 하였고 , Dummy Object, Test Stub, Test Spy Mock Object, Fake Object 등으로 분류하였다

(4) 목 오브젝트 생성과 활용을 도와주는 프레임워크로 Mockito, Spock 등이 있다 .

(5) 목 오브젝트는 정말 필요한지 잘 따져보고 , ROI 가 확실할 때만 사용해야 하며 , 가장 중요한 것은 ! 목 오브젝트는 단지 모조품일 뿐이고 , 처음부터 실제 객체로 테스트 할 수 있다면 목 오브젝트를 쓰지 말자

Page 36: 목 오브젝트(Mock Object)의 이해

참고자료5. 정리

(1) 책 가격 계산기 예제 프로젝트 코드 : https://github.com/bluepoet/BookPriceCalculator

(2) 채수원 저 “테스트 주도 개발 : 고품질 쾌속개발을 위한 TDD 실천법과 도구”

(3) 라쎄 코스켈라 저 “ Effective Unit Testing”

(4) 최범균 저 “개발자가 반드시 정복해야 할 객체지향과 디자인패턴”

(5) JI 개발리뷰 발표자료 : http://javacan.tistory.com/376

(6) 모델링 연습 리뷰 자료 : http://javacan.tistory.com/entry/Modeling-Practice-Review

Page 37: 목 오브젝트(Mock Object)의 이해

감사합니다