TIL) Unit test - mocking

Jiwon Lee·2022년 8월 1일
0

Mocking이란?

자체 서버만을 이용하는 것이 아닌, 데이터베이스 또는 외부의 API에 의존하여 코드를 테스트 해야하는 일이 생기는데, (나는 이번 개인 프로젝트에서 소셜로그인(kakao) API에 대한 unit test를 작성할 때에 이 상황을 겪었다.) 그 외부에 의존하는 부분을 임의로 값을 주어 대체하는 테스팅 기법을 모킹(mocking)이라고 한다.
unittest.mock 모듈은 파이썬 자체에 기본 내장된 모킹 라이브러리이기 때문에 별도의 설치 없이 import하여 사용하면 된다.

>>> from unittest.mock	import Mock, MagicMock

Mock객체 설정하기

우선 mock이라고 하는 임의의 가짜 객체를 생성한다. 이 mock객체는 호출되었을 때에 특정한 값을 리턴할 수 있는데, return_value옵션을 사용하여 쓸 수 있다.

>>> mock = Mock(return_value="Hello World!")
>>> mock()
"Hello World!"

또한, 호출이 되었을 때에 예외사항을 지정하고 싶다면, side_effect옵션을 이용하면 된다. side_effect옵션에 함수를 넘기면, mock객체를 호출했을 때에 주어진 인자에 따라 다른 값을 리턴할 수 있다.

>>> mock = Mock(side_effect=lambda x:x * 10)
>>> mock(1)
10
>>> mock(2)
20

MagicMock이란?

Python에는 매직 매서드(Magic Method)라는 개념이 있는데, 모든 객체에는 언어 레벨에서 특수한 목적으로 쓰이는 메서드를 정의할 수 있다는 것이다. 대표적으로 __str__의 경우, 객체를 읽기 좋은 형태의 '문자열'로 출력하기 위해서 사용되는 매직 메서드 이다.
그렇지만 기본적으로 Mock 클래스를 사용하게되면 이러한 매직 메서드는 자동으로 모킹이 되지 않는다. 때문에, 매직 메서드를 모킹하려면, 다른 속성이나 메서드와는 달리 아래와 같이 새로운 mock객체를 직접 생성해서 할당해줘야한다.

>>> mock.__str__ = Mock(return_value="I'm lizzy")
>>> str(mock)
"I'm lizzy"

이러한 불편함을 해소하기 위해 Mock클래스의 확장 버전인 MagicMock 클래스를 사용한다. 알아서 매직 메서드를 미리 모킹해놓아 주어 편리하기 때문.

>>> from unittest.mock	import MagicMock
>>> mock = MagicMock()
>>> mock.__str__.return_value = "I'm lizzy"
>>> str(mock)
"I'm lizzy"

  • 실제 프로젝트에서 유닛테스트를 작성할 때에는 직접 하나하나 mock 객체를 생성하기 보다는 patch()데코레이터를 사용하는 것이 일반적이라고 한다. 이 부분은 다음 포스팅에서!

0개의 댓글