2017-01-03 4 views
0

로깅 모듈을 테스트하고 싶습니다. 나는 선을 생성하고 파일에 쓰는 함수가있다. 나는 다음과 같은 코드가 있습니다 :Python의 모의 파일 스트림

class Unit_test(unittest.TestCase): 
    @patch('my_logger.generate_line', return_value='abc') 
    def test_write_line_to_log_file(self, arg1): 
     with patch('my_logger.open_file_stream', return_value=StringIO.StringIO()) as f: 
      my_logger.write_line_to_log_file(message='message123', pid=1234, 
              module='abc/def', state='OK', 
              data={'test_key': 'test_value'}) 
      should_be = 'abc' 
      f.seek(0) 
      self.assertEqual(f.readline(), should_be) 

가 나는 그것이 파일 스트림에 콘텐츠를 쓰는 경우 패치가 내가 읽고 확인할 수 있습니다 실제 개체를 만들 것이라고 생각 : 나는 다음과 같은 코드로 테스트 기능 write_line_to_log_file을 시도

def open_file_stream(filename, opt): 
    return open(filename, opt) 

def close_file_stream(f): 
    f.close() 

def write_line_to_log_file(message, pid, module, state, data={}, datatype='AKV'): 
    file_path = '/path/to/file' 
    try: 
     f = open_file_stream(file_path, 'a') 
     # generate_line only takes the arguments and formats it to string 
     f.write(generate_line(message, pid, module, state, data, 'AKV') + '\n') 
    except Exception as e: 
     raise RuntimeError('Failed to write log line to %s: %s' % (file_path, str(e))) 
    finally: 
     f.close() 

예상대로 대신 :

AssertionError: <MagicMock name='open_file_stream.readline()' id='3066213676'> != 'abc' 

어떻게 수정해야합니까? 또는 콘텐츠가이 MagicMock 개체에 있다면 어떻게 읽어야합니까?

답변

0

먼저 자신의 코드가 아닌 외부 리소스를 조롱해야합니다. 이 경우 open입니다. mock 라이브러리 형식의 mock_open을 사용하여 테스트를 테스트 할 수 있습니다.

의 당신이 여기에이 코드를 가지고 있다고 가정 해 봅시다 당신의 my_module.py

def write_contents(contents): 
    try: 
     with open('/my/path', 'w') as fh: 
      fh.write(contents) 
    except IOError: 
     print "Something wrong happened" 

당신은 mock_open

import mock 
import unittest 

import my_module 

class TestClass(unittest.TestCase): 
    def test_my_module(self): 
     m = mock.mock_open() 
     with mock.patch('my_module.open', m, create=True) as mocked_open: 
      contents = "Sample write content" 
      my_module.write_contents(contents) 
      file_handle = mocked_open() 
      # Do the assert 
      file_handle.write.assert_called_once_with(contents, 'w') 

이 방법은 파이썬을 말하고있다을 사용하여 다음 테스트 케이스를 가질 수 시험의 실행 중 새 open 메서드가 있다고 가정하고 예상대로 동작하는지 확인합니다.

with patch('my_logger.open_file_stream', return_value=StringIO.StringIO()) as f:을 할 때 f는 추가하는 내용 만 포함하는 mock 객체입니다. 즉, return_value 속성을 지정하거나 side_effect를 지정합니다.

귀하의 경우에 위의 예를 조정할 수 있습니다. file_handle 개체는 다른 open 개체와 비슷하게 작동하며 write, read, readinto 등의 메서드를 사용하여 원하는대로 테스트 할 수 있습니다.

+0

''w''이 적용될 때 마지막 행의 Assert가 작동하지 않지만 모든 것이 작동합니다. 감사! – thecoparyew