단위 테스트를 원하는 함수가 있는데 두 개의 다른 함수를 호출합니다. 패치를 사용하여 두 기능을 동시에 적절하게 모의 할 수있는 방법이 확실하지 않습니다. 나는 아래에 내가 의미하는 바의 예를 제공했습니다. nosetest를 실행하면 테스트는 통과하지만이를 수행하는 더 깨끗한 방법이 있어야한다고 생각하며 f.close ()에 관한 부분을 실제로 이해하지 못합니다.
디렉토리 구조는 다음과 같습니다.
program/
program/
data.py
tests/
data_test.py
data.py :
import cPickle
def write_out(file_path, data):
f = open(file_path, 'wb')
cPickle.dump(data, f)
f.close()
data_test.py :
from mock import MagicMock, patch
def test_write_out():
path = '~/collection'
mock_open = MagicMock()
mock_pickle = MagicMock()
f_mock = MagicMock()
with patch('__builtin__.open', mock_open):
f = mock_open.return_value
f.method.return_value = path
with patch('cPickle.dump', mock_pickle):
write_out(path, 'data')
mock_open.assert_called_once_with('~/collection', 'wb')
f.close.assert_any_call()
mock_pickle.assert_called_once_with('data', f)
결과 :
$ nosetests
.
----------------------------------------------------------------------
Ran 1 test in 0.008s
OK
답변
패치 데코레이터를 사용하고 다음과 같이 중첩하여 테스트를 단순화 할 수 있습니다 ( MagicMock
기본적으로 객체입니다).
@patch('cPickle.dump')
@patch('__builtin__.open')
def test_write_out(mock_open, mock_pickle):
path = '~/collection'
f = mock_open.return_value
f.method.return_value = path
write_out(path, 'data')
mock_open.assert_called_once_with('~/collection', 'wb')
mock_pickle.assert_called_once_with('data', f)
f.close.assert_any_call()
MagicMock
인스턴스를 호출 하면 새 MagicMock
인스턴스가 반환되므로 반환 된 값이 다른 모의 객체와 마찬가지로 호출되었는지 확인할 수 있습니다. 이 경우 f
에는 MagicMock
이름이 지정됩니다 'open()'
(인쇄 시도 f
).
답변
@Matti John 응답 외에도 patch
내부 함수 를 사용할 수도 있습니다 test_write_out
.
from mock import MagicMock, patch
def test_write_out():
path = '~/collection'
with patch('__builtin__.open') as mock_open, \
patch('cPickle.dump') as mock_pickle:
f = mock_open.return_value
...
답변
여기에 간단한 예제가 어떻게 제기 테스트에 ConflictError
에 create_collection
모의를 사용 기능 :
import os
from unittest import TestCase
from mock import patch
from ..program.data import ConflictError, create_collection
class TestCreateCollection(TestCase):
def test_path_exists(self):
with patch.object(os.path, 'exists') as mock_method:
mock_method.return_value = True
self.assertRaises(ConflictError, create_collection, 'test')
mock 문서 와 Michael Foord의 멋진 mock 소개 도 참조하십시오 .