[Test] Test Double

Falcon·2023년 5월 31일
1

typescript

목록 보기
3/6
post-thumbnail

Test Double : Mocks vs Stubs

Test double 은 테스트하는 동안 프로덕션과 유사한 환경을 구성하기 위한 객체를 의미한다.

테스트 코드에서 데이터를 읽고 쓰거나 DB에 영향을 미치는 것은 서비스에 영향을 줄수 있으므로 좋지 않다.

이를 우회하기 위한 두가지 기법 크게 2가지 있는데 바로 mock 과 stub 이다.

Mocks : Mock & Spy

'Behavior' (행위)를 검증하기 위한 테스트 기법

Mock

  • 특정 메소드 혹은 클래스를 통째로 빈 구현체로 갈아넣을 때.
  • 특정 메소드에 대해 특정 구현체 혹은 반환 값을 가지게 할 때

Example

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..
})

Spy

  • 함수를 진짜로 대체하지 않고 호출 경위 / 시나리오만 파악할 때

ex) jest.spyOn(, 'methodName')

'Wrappers' Empty replacements for functions that allow you track if & how functiion was called.

ex) whethe r it's executed.

Stub

테스트에 필요한 최소기능만 구현 해놓은 구현체.
Jest는 spyOn() + mockImplementation() 으로 구현하고
ts-mockito , sinonJs 는 stub 구현을 지원한다.

Summary

IndexMockSpyStub
When to useReplace method as emptyMonitoring specific methodReplace method as specific spec when it's hard to implement required spec
Why to useBehavior verificationTest without effect on original implementationState Verification
How to usejest.fn(), jest.mock('module')jest.spyOn('module', 'method')Predefine return value

Spy doesn't change target implementation itself.

State Verification => Use stub

After action, Assert status of object.

Behavior Verification => Use mock

After action, Assert next action

결국 Stub 은 When - Then 에 대한 사전 정의값이고
mock 은 호출 시나리오/횟수를 파악하기 위한 도구다.


Stub : Stub vs Fake vs Dummy

State (상태)를 검증하기 위한 도구

Stub

Stub 은 returnValue 를 미리 정의한 것이나 상관없다.
보통 when(Condition) - then(Return) 을 정의해둔 객체다.
어떤 input 이 들어오든 사전에 정의한 output 을 내놓는다.

ex) 쿼리문 - 결과 같은 경우.
input: null -> output: null

Fake

테스트만을 위한 실제 구현체다.
따라서 Stub 보다 더 많은 코드를 작성해야하고 실제 인터페이스에서 제공하는 모든 행위를 구현해야한다.

Fakes are more complex and simulate the behavior of the real object.

Dummy

오로지 파라미터 값을 채우기 위한 깡통 데이터.
보통 null, empty string('') 같은 데이터가 이에 해당한다.


🔗 Reference

profile
I'm still hungry

0개의 댓글