오늘도 개발

pytest 사용법 2) mock 본문

웹 프로그래밍/Python3

pytest 사용법 2) mock

Sueeeeeee 2023. 1. 19. 01:08

1. Mocking

mocking이란?

유닛테스트에서 함수의 return값을 대체시키는 작업.

테스트 시 실행되면 안 되는 작업에 사용한다. (예 : 사용자에게 문자 보내기)

 

pytest에서는 함수 내에 있는 함수의 반환값을 대체하는 식으로 사용한다.

 

2.  mock을 사용하지 않은 경우

<views.py>

def divide(num):
    try:
        10 / num
        print('success!!')
        return True
    except ZeroDivisionError:
        print('failed!!')
        return False

def outer(num):
    num *= 10
    return divide(num)

<tests.py>

test_outer가 outer 함수를 실행하면 divide 함수가 실행된다.

'failed!!'가 결과의 stdout call에 뜬다.

import pytest

from arithmatic.views import outer, divide

@pytest.mark.django_db
class TestGreet:
    @pytest.fixture
    def num(self):
        return 0

    def test_outer(self, num):
        outer(num)
        assert False

3.  mock을 사용하는 경우

<views.py>

from arithmatic.utils import divide

def outer(num):
    num *= 10
    return divide(num)

 

<utils.py>

def divide(num):
    try:
        10 / num
        print('success!!')
        return True
    except ZeroDivisionError:
        print('failed!!')
        return False

 

<tests.py>

divide 함수가 호출은 되는데 실행은 안 된다.

실행이 안 되기 때문에 'failed!!'가 결과의 stdout call에 뜨지 않는다.

경우에 따라 mock_divide.return_value = True 처럼 반환값을 지정해줄 수도 있다. 

 

@mock.patch()안에는 mock할 함수를 정의한 곳의 경로(arithmatic.utils.divide)가 아니라

호출하는 곳의 경로(arithmatic.views.divide)를 적어주어야 한다.

호출하는 곳을 적지 않으면 mock이 실행되지 않는다. 

from unittest import mock

from arithmatic.views import outer

@pytest.mark.django_db
class TestGreet:
    @pytest.fixture
    def num(self):
        return 0

    @mock.patch('arithmatic.views.divide') # 모킹할 함수를 경로와 함께 적어준다.
    def test_outer(self, mock_divide, num): # 모킹된 함수를 부를 이름을 인수에 넣어준다.
        outer(num)
        mock_divide.assert_called() # True

 

'웹 프로그래밍 > Python3' 카테고리의 다른 글

all(), any()  (0) 2023.02.18
pytest 사용법 1) 설정, fixture, parametrize  (0) 2023.01.18
pyenv와 pyenv-virtualenv  (0) 2023.01.03
setdefault와 defaultdict  (0) 2022.12.23
Python의 GC(Garbage Collection)  (0) 2022.10.31