Test double 은 테스트하는 동안 프로덕션과 유사한 환경을 구성하기 위한 객체를 의미한다.
테스트 코드에서 데이터를 읽고 쓰거나 DB에 영향을 미치는 것은 서비스에 영향을 줄수 있으므로 좋지 않다.
이를 우회하기 위한 두가지 기법 크게 2가지 있는데 바로 mock 과 stub 이다.
'Behavior' (행위)를 검증하기 위한 테스트 기법
tsyringe + jest 환경에서 mocking 해보기
describe('Adapter test',()=>{
let adapter: InputAdapter
beforeAll(()=>{
const mockInPort: IInPort = {
method1: jest.fn(),
method2: jest.fn()
}
const mockOutPort: IOutPort = {
method1: jest.fn(),
method2: jest.fn()
}
// 독립적인 컨테이너에 mock 인스턴스 등록
adapter = container.createChildContainer()
.register('IInPort', {useValue: mockInputPort}) // mocking 등록
.register('IOutPort', {useValue: mockOutputPort}) // mocking 등록
.resolve(InputAdapter)
})
// test..
})
ex) jest.spyOn(, 'methodName')
'Wrappers' Empty replacements for functions that allow you track if & how functiion was called.
ex) whethe r it's executed.
테스트에 필요한 최소기능만 구현 해놓은 구현체.
Jest는 spyOn()
+ mockImplementation()
으로 구현하고
ts-mockito , sinonJs 는 stub 구현을 지원한다.
Index | Mock | Spy | Stub |
---|---|---|---|
When to use | Replace method as empty | Monitoring specific method | Replace method as specific spec when it's hard to implement required spec |
Why to use | Behavior verification | Test without effect on original implementation | State Verification |
How to use | jest.fn(), jest.mock('module') | jest.spyOn('module', 'method') | Predefine return value |
Spy doesn't change target implementation itself.
After action, Assert status of object.
After action, Assert next action
결국 Stub 은 When - Then 에 대한 사전 정의값이고
mock 은 호출 시나리오/횟수를 파악하기 위한 도구다.
State (상태)를 검증하기 위한 도구
Stub 은 returnValue 를 미리 정의한 것이나 상관없다.
보통 when(Condition) - then(Return) 을 정의해둔 객체다.
어떤 input 이 들어오든 사전에 정의한 output 을 내놓는다.
ex) 쿼리문 - 결과 같은 경우.
input: null -> output: null
테스트만을 위한 실제 구현체다.
따라서 Stub 보다 더 많은 코드를 작성해야하고 실제 인터페이스에서 제공하는 모든 행위를 구현해야한다.
Fakes are more complex and simulate the behavior of the real object.
오로지 파라미터 값을 채우기 위한 깡통 데이터.
보통 null, empty string('') 같은 데이터가 이에 해당한다.