[PYTHON] 단위 테스트에서 open (file_name) 조롱
PYTHON단위 테스트에서 open (file_name) 조롱
csv 파일을 열고 헤더를 설정하는 소스 코드가 있습니다. 가치 협회. 소스 코드는 다음과 같습니다.
def ParseCsvFile(source):
"""Parse the csv file.
Args:
source: file to be parsed
Returns: the list of dictionary entities; each dictionary contains
attribute to value mapping or its equivalent.
"""
global rack_file
rack_type_file = None
try:
rack_file = source
rack_type_file = open(rack_file) # Need to mock this line.
headers = rack_type_file.readline().split(',')
length = len(headers)
reader = csv.reader(rack_type_file, delimiter=',')
attributes_list=[] # list of dictionaries.
for line in reader:
# More process to happeng. Converting the rack name to sequence.
attributes_list.append(dict((headers[i],
line[i]) for i in range(length)))
return attributes_list
except IOError, (errno, strerror):
logging.error("I/O error(%s): %s" % (errno, strerror))
except IndexError, (errno, strerror):
logging.error('Index Error(%s), %s' %(errno, strerror))
finally:
rack_type_file.close()
다음 진술을 조롱하려고합니다.
rack_type_file = open(rack_file)
오픈 (...) 기능을 어떻게 조롱합니까?
해결법
-
==============================
1.이것은 낡은 질문이기 때문에 일부 답변이 오래된 것입니다.
이것은 낡은 질문이기 때문에 일부 답변이 오래된 것입니다.
모의 라이브러리의 현재 버전에는 정확히이 목적을 위해 설계된 편의 함수가 있습니다. 다음은 작동 방식입니다.
>>> from mock import mock_open >>> m = mock_open() >>> with patch('__main__.open', m, create=True): ... with open('foo', 'w') as h: ... h.write('some stuff') ... >>> m.mock_calls [call('foo', 'w'), call().__enter__(), call().write('some stuff'), call().__exit__(None, None, None)] >>> m.assert_called_once_with('foo', 'w') >>> handle = m() >>> handle.write.assert_called_once_with('some stuff')
문서는 여기에 있습니다.
-
==============================
2.mox를 사용하여 내장 함수를 모의 사용하려면 __builtin__ module을 사용하십시오.
mox를 사용하여 내장 함수를 모의 사용하려면 __builtin__ module을 사용하십시오.
import __builtin__ # unlike __builtins__ this must be imported m = mox.Mox() m.StubOutWithMock(__builtin__, 'open') open('ftphelp.yml', 'rb').AndReturn(StringIO("fake file content")) m.ReplayAll() # call the code you want to test that calls `open` m.VerifyAll() m.UnsetStubs()
__builtins__은 항상 모듈이 아니며 dict 유형일 수 있습니다. 시스템 내장 메서드를 참조하려면 __builtin__ ( "s"없음) 모듈을 사용하십시오.
__builtin__ 모듈에 대한 추가 정보 : http://docs.python.org/library/builtin.html
-
==============================
3.상황에 따라이 작업을 수행하는 두 가지 방법이 있습니다.
상황에 따라이 작업을 수행하는 두 가지 방법이 있습니다.
만약 당신의 유닛 테스트가 ParseCsvFile을 직접 호출한다면 나는 ParseCsvFile에 새로운 kwarg를 추가 할 것입니다 :
def ParseCsvFile(source, open=open): # ... rack_type_file = open(rack_file) # Need to mock this line.
그런 다음 단위 테스트는 조롱을 달성하기 위해 다른 open_func를 전달할 수 있습니다.
유닛 테스트가 ParseCsvFile을 호출하는 다른 함수를 호출하면 테스트를 위해 open_func를 전달하는 것은 추악합니다. 이 경우 모의 모듈을 사용할 것입니다. 이를 통해 함수를 이름으로 변경하고 모의 객체로 대체 할 수 있습니다.
# code.py def open_func(name): return open(name) def ParseCsvFile(source): # ... rack_type_file = open_func(rack_file) # Need to mock this line. # test.py import unittest import mock from StringIO import StringIO @mock.patch('code.open_func') class ParseCsvTest(unittest.TestCase): def test_parse(self, open_mock): open_mock.return_value = StringIO("my,example,input") # ...
-
==============================
4.데코레이터 (Python3)로 간단합니다 :
데코레이터 (Python3)로 간단합니다 :
def my_method(): with open(file="/1.txt", mode='r', encoding='utf-8') as file: return file.read().strip() @mock.patch("builtins.open", create=True) def test_my_method(mock_open): mock_open.side_effect = [ mock.mock_open(read_data="A").return_value ] resA = my_method() assert resA == "A" mock_open.mock_calls == [mock.call(file="/1.txt", mode='r', encoding='utf-8')]
-
==============================
5.나는 샘플 함수를 다시 쓰는 자유를 얻었다.
나는 샘플 함수를 다시 쓰는 자유를 얻었다.
함수가 code.py라는 파일에 있다고 가정합니다.
# code.py import csv import logging def ParseCsvFile(source): """Parse the csv file. Args: source: file to be parsed Returns: the list of dictionary entities; each dictionary contains attribute to value mapping or its equivalent. """ global rack_file rack_file = source attributes_list = [] try: rack_type_file = open(rack_file) except IOError, (errno, strerror): logging.error("I/O error(%s): %s", errno, strerror) else: reader = csv.DictReader(rack_type_file, delimiter=',') attributes_list = [line for line in reader] # list of dictionaries rack_type_file.close() return attributes_list
간단한 테스트 케이스는 다음과 같습니다.
# your test file import __builtin__ import unittest import contextlib from StringIO import StringIO import mox import code @contextlib.contextmanager def mox_replayer(mox_instance): mox_instance.ReplayAll() yield mox_instance.VerifyAll() class TestParseCSVFile(unittest.TestCase): def setUp(self): self.mox = mox.Mox() def tearDown(self): self.mox.UnsetStubs() def test_parse_csv_file_returns_list_of_dicts(self): TEST_FILE_NAME = 'foo.csv' self.mox.StubOutWithMock(__builtin__, 'open') open(TEST_FILE_NAME).AndReturn(StringIO("name,age\nfoo,13")) with mox_replayer(self.mox): result = code.ParseCsvFile(TEST_FILE_NAME) self.assertEqual(result, [{'age': '13', 'name': 'foo'}]) # works! if __name__ == '__main__': unittest.main()
편집하다:
% /usr/bin/python2.6 Python 2.6.1 (r261:67515, Jun 24 2010, 21:47:49) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits" or "license" for more information. >>> import __builtin__ >>> import mox >>> mock = mox.Mox() >>> mock.StubOutWithMock(__builtin__, 'open') >>> mock.UnsetStubs()
Mox 0.53을 사용하여 2.6에서 정상적으로 작동합니다.
-
==============================
6.안녕 비슷한 문제가 있었는데, 다른 mocking 라이브러리 사이에 내 머리카락이 튀어 나와 밖으로 찢어지고 있었다. 마침내 내가 만족스럽고 어쩌면 도움이 될만한 해결책을 찾았습니까? 결국 나는 Mocker 라이브러리 http://labix.org/mocker와 함께 갔고, 여기에 조롱을위한 코드가있다 :
안녕 비슷한 문제가 있었는데, 다른 mocking 라이브러리 사이에 내 머리카락이 튀어 나와 밖으로 찢어지고 있었다. 마침내 내가 만족스럽고 어쩌면 도움이 될만한 해결책을 찾았습니까? 결국 나는 Mocker 라이브러리 http://labix.org/mocker와 함께 갔고, 여기에 조롱을위한 코드가있다 :
from mocker import Mocker from StringIO import StringIO import __builtin__ mocker = Mocker() sourceFile = 'myTestFile.txt' __builtin__.open = mocker.mock() __builtin__.open(sourceFile) mocker.result(StringIO('this,is,a,test,file')) <the rest of your test setup goes here> mocker.replay() ParseCsvFile(sourceFile) mocker.restore() mocker.verify()
Incidentaly 내가 Mocker와 함께 갔던 이유는 파일을 읽기 위해 열린 함수를 테스트하고 있었기 때문에 같은 파일을 새로운 데이터로 덮어 쓰는 데 다시 open 함수를 사용했기 때문입니다. 내가 할 수 있기를 원하는 것은 초기 파일이 존재하지 않는 경우를 테스트하는 것이므로 처음으로 IOError를 던진 모의를 설정 한 다음 두 번째로 작업했습니다. 이 설정은 다음과 같습니다.
from mocker import Mocker import __builtin__ mocker = Mocker() mockFileObject = mocker.mock() __builtin__.open = mocker.mock() __builtin__.open('previousState.pkl', 'r') mocker.throw(IOError('Boom')) __builtin__.open('previousState.pkl','w') mocker.result(mockFileObject) <rest of test setup > mocker.replay() <test> mocker.restore() #required to restore the open method mocker.verify()
희망이 도움이!
-
==============================
7.
>>> class A(object): ... def __init__(self): ... self.x = open('test.py') ... >>> old_open = open >>> def open(s): ... return "test\n" ... >>> a = A() >>> a.x 'test\n' >>> open = old_open >>> a = A() >>> a.x <open file 'test.py', mode 'r' at 0xb7736230>
-
==============================
8.@ mock.patch 데코레이터 (2.7 예)
@ mock.patch 데코레이터 (2.7 예)
이제 훨씬 쉬워졌습니다.
import your_script.py import __builtin__ import mock @mock.patch("__builtin__.open") def test_example(self, mock_open): your_script.your_method() self.assertEqual(mock_open.call_count, 1)
from https://stackoverflow.com/questions/5237693/mocking-openfile-name-in-unit-tests by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 동일한 속성을 참조하는 SQLAlchemy ORM에서 자체 참조 다 대다 관계를 어떻게 성취 할 수 있습니까? (0) | 2018.10.23 |
---|---|
[PYTHON] 파이썬`for` 문법 : 블럭 코드 vs 싱글 라인 생성자 표현식 (0) | 2018.10.23 |
[PYTHON] Tensorflow r1.0 : 요구 사항을 만족하는 버전을 찾을 수 없습니다. tensorflow (0) | 2018.10.23 |
[PYTHON] 없음 값이있는 Pyspark 데이터 프레임 열 필터링 (0) | 2018.10.23 |
[PYTHON] Python의 unittest 및 동적 테스트 케이스 생성 [duplicate] (0) | 2018.10.23 |