테스트 할때 redis를 어떻게 처리할까

임채욱·2022년 5월 7일
2
post-thumbnail

최근 사이드 프로젝트에서 했던 고민들을 정리하는 시간을 가지고 있는데 몇몇 내용은 블로그에 올려도 좋겠다는 생각이 들어 이렇게 올리게 되었다.

사이드 프로젝트에서 이메일 인증 코드, 몇몇 api의 캐싱 용도로 redis를 사용하고 있는데 이러한 부분에 테스트를 붙일때 어떻게 할지에 대한 고민을 정리해보았다.

  1. test용 redis를 띄운다
  2. redis를 mocking해서 사용한다

test용 redis

문제점

redis를 mocking 하기

자바 스프링에서는 목킹하는 예시가 자주 보인다

혹은 embedded redis를 사용해서 테스트 하기도 한다

여러모로 테스트해본 결과 그냥 목킹해서 하는게 오히려 제일 편할수 있을거 같다

별도의 모듈로 분리하여 사용하기

테스트 코드를 만들다 보니 redis를 mocking하는게 아니라 cache module에서 redis에 접근하고 cache module을 mocking하는게 편할 수도 있다는 결론이 나왔다

cache module에 redis 함수 자체를 제공하기 보다는 명확한 인터페이스를 만들어 기능을 분리하도록 하였다.

async setIntraAuthMailData(code: string, value: IntraAuthMailDto) {
    await this.cacheManager.set<IntraAuthMailDto>(code, value, {
      ttl: TIME2LIVE,
    });
  }

mocking은 다음과 같은 방식으로 하였다.

...
providers: [
        IntraAuthService,
        {
          provide: MailerService,
          useValue: {
            sendMail: sendMailMock,
          },
        },
        {
          provide: CacheService,
          useValue: {
            setIntraAuthMailData: jest.fn(),
            getIntraAuthMailData: jest.fn(),
            del: jest.fn(),
          },
        },
      ],
...

jest가 아닌 ts-mockito

위에서는 jest를 사용하여 mocking하였으나 테스트 코드 내부에서 내가 예상하는 결과를 만들어내기는 어려웠다.

그래서 jest.mock 보다 ts-mockito 사용하기 (feat. Node.js)
를 참고하여 ts-mockito를 적용해보았다

적용한 결과는 다음과 같다

const cacheService: CacheService = mock(CacheService);
const mailerService: MailerService = mock(MailerService);

...
providers: [
        IntraAuthService,
        {
          provide: MailerService,
          useValue: {
            sendMail: mailerService.sendMail,
          },
        },
        {
          provide: CacheService,
          useValue: instance(cacheService),
        },
      ],
...

그리고 아래와 같이 사용하였다

when(cacheService.getIntraAuthMailData(mailCode)).thenResolve(
  new IntraAuthMailDto(cadetUser.id, intraId),
);

위와 같은 when을 호출한 뒤에 실행되는 코드는 thenResoleve에 지정한 값을 리턴하도록 만들수 있다

jest로는 위와 같은 원하는 값을 리턴하도록 만드려면 spyOn을 사용하여야 했다

문제는 알아보기 어렵고 자동완성도 안되는 문자열로 함수 이름을 지정해야 했기에 불편함이 있었다

다행히 ts-mockito가 이러한 과정을 편하게 할 수 있도록 개선해줬고 지금까지 잘사용하고 있다

ts-mockito가 더이상 업데이트가 안 되는 상황이기는 하지만 큰 문제가 없는 한 계속 사용할 것 같다

profile
성장을 추구하는 개발자입니다

0개의 댓글