Python 은 유닛 테스트 에서 대상 에 게 패 치 를 어떻게 합 니까?
당신 이 쓴 단원 테스트 에 서 는 지정 한 대상 에 게 패 치 를 쳐 서 테스트 에서 의 기대 행 위 를 단언 해 야 합 니 다(예 를 들 어 호출 된 매개 변수 개수,지정 한 속성 에 접근 하 는 등).
해결 방안
unittest.mock.patch()
함 수 는 이 문 제 를 해결 하 는 데 사용 할 수 있다.patch()
장식 기,컨 텍스트 관리자 또는 단독 사용 으로 도 사용 할 수 있 습 니 다.흔 하지 않 지만.예 를 들 어 다음은 장식 기로 사용 하 는 예 입 니 다.
from unittest.mock import patch
import example
@patch('example.func')
def test1(x, mock_func):
example.func(x) # Uses patched example.func
mock_func.assert_called_with(x)
컨 텍스트 관리자 로 도 사용 할 수 있 습 니 다.
with patch('example.func') as mock_func:
example.func(x) # Uses patched example.func
mock_func.assert_called_with(x)
마지막 으로 패 치 를 수 동 으로 사용 할 수 있 습 니 다.
p = patch('example.func')
mock_func = p.start()
example.func(x)
mock_func.assert_called_with(x)
p.stop()
가능 하 다 면 장식 기와 컨 텍스트 관리 자 를 겹 쳐 여러 대상 에 게 패 치 를 할 수 있 습 니 다.예 를 들 면:
@patch('example.func1')
@patch('example.func2')
@patch('example.func3')
def test1(mock1, mock2, mock3):
...
def test2():
with patch('example.patch1') as mock1, \
patch('example.patch2') as mock2, \
patch('example.patch3') as mock3:
...
토론 하 다.patch()
존재 하 는 대상 의 전체 경로 이름 을 받 아들 여 새로운 값 으로 바 꿉 니 다.원래 값 은 장식 기 함수 나 컨 텍스트 관리자 가 완 료 된 후에 자동 으로 회 복 됩 니 다.기본적으로 모든 값 은MagicMock
인 스 턴 스 로 대 체 됩 니 다.예 를 들 면:
>>> x = 42
>>> with patch('__main__.x'):
... print(x)
...
<MagicMock name='x' id='4314230032'>
>>> x
42
>>>
단,patch()
에 두 번 째 인 자 를 제공 함으로써 원 하 는 것 으로 값 을 바 꿀 수 있 습 니 다.
>>> x
42
>>> with patch('__main__.x', 'patched_value'):
... print(x)
...
patched_value
>>> x
42
>>>
교체 값 으로 사 용 된MagicMock
인 스 턴 스 는 호출 가능 한 대상 과 인 스 턴 스 를 모 의 할 수 있 습 니 다.그들 은 대상 의 사용 정 보 를 기록 하고 단언 검 사 를 허용 합 니 다.예 를 들 어:
>>> from unittest.mock import MagicMock
>>> m = MagicMock(return_value = 10)
>>> m(1, 2, debug=True)
10
>>> m.assert_called_with(1, 2, debug=True)
>>> m.assert_called_with(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File ".../unittest/mock.py", line 726, in assert_called_with
raise AssertionError(msg)
AssertionError: Expected call: mock(1, 2)
Actual call: mock(1, 2, debug=True)
>>>
>>> m.upper.return_value = 'HELLO'
>>> m.upper('hello')
'HELLO'
>>> assert m.upper.called
>>> m.split.return_value = ['hello', 'world']
>>> m.split('hello world')
['hello', 'world']
>>> m.split.assert_called_with('hello world')
>>>
>>> m['blah']
<MagicMock name='mock.__getitem__()' id='4314412048'>
>>> m.__getitem__.called
True
>>> m.__getitem__.assert_called_with('blah')
>>>
일반적으로 이 조작 들 은 한 단원 테스트 에서 이 루어 진다.예 를 들 어 아래 와 같은 함수 가 있다 고 가정 합 니 다.
# example.py
from urllib.request import urlopen
import csv
def dowprices():
u = urlopen('http://finance.yahoo.com/d/quotes.csv?s=@^DJI&f=sl1')
lines = (line.decode('utf-8') for line in u)
rows = (row for row in csv.reader(lines) if len(row) == 2)
prices = { name:float(price) for name, price in rows }
return prices
일반적으로 이 함 수 는 웹 에서 데 이 터 를 가 져 와 분석 합 니 다.유닛 테스트 에서 미리 정 의 된 데이터 세트 를 줄 수 있 습 니 다.다음은 패 치 작업 의 예 입 니 다.
import unittest
from unittest.mock import patch
import io
import example
sample_data = io.BytesIO(b'''\
"IBM",91.1\r
"AA",13.25\r
"MSFT",27.72\r
\r
''')
class Tests(unittest.TestCase):
@patch('example.urlopen', return_value=sample_data)
def test_dowprices(self, mock_urlopen):
p = example.dowprices()
self.assertTrue(mock_urlopen.called)
self.assertEqual(p,
{'IBM': 91.1,
'AA': 13.25,
'MSFT' : 27.72})
if __name__ == '__main__':
unittest.main()
이 예 에서urlopen()
모듈 에 있 는example
함수 가 아 날로 그 대상 으로 대체 되 고 이 대상 은 테스트 데 이 터 를 포함 한urlopen()
을 되 돌려 줍 니 다.또 하 나 는 패 치 를 할 때 우 리 는
ByteIO()
대신example.urlopen
을 사용 했다.패 치 를 만 들 때 테스트 코드 에 있 는 이름 을 사용 해 야 합 니 다.테스트 코드 가 사용urllib.request.urlopen
되 었 기 때문에from urllib.request import urlopen
함수 에서 사용 하 는dowprices()
함 수 는 실제urlopen()
모듈 에 있 습 니 다.이 절 은 사실상
example
모듈 에 대한 수박 겉 핥 기 일 뿐이다.더 많은 고 급 스 러 운 특성 을 참고 하 시기 바 랍 니 다공식 문서이상 은 파 이 썬 이 유닛 테스트 에서 대상 에 게 패 치 를 하 는 방법 에 대한 상세 한 내용 입 니 다.파 이 썬 유닛 테스트 에 관 한 자 료 는 우리 의 다른 관련 글 을 주목 하 세 요!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Python의 None과 NULL의 차이점 상세 정보그래서 대상 = 속성 + 방법 (사실 방법도 하나의 속성, 데이터 속성과 구별되는 호출 가능한 속성 같은 속성과 방법을 가진 대상을 클래스, 즉 Classl로 분류할 수 있다.클래스는 하나의 청사진과 같아서 하나의 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.