Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/mercurial/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python中的模拟文件流_Python_Python 2.7_Mocking - Fatal编程技术网

python中的模拟文件流

python中的模拟文件流,python,python-2.7,mocking,Python,Python 2.7,Mocking,我想测试我的日志模块。我有一个函数,生成一行并将其写入文件。我有以下代码: 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 = '/pa

我想测试我的日志模块。我有一个函数,生成一行并将其写入文件。我有以下代码:

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()
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)
我尝试用以下代码测试函数
将行写入日志文件

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()
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)
我认为该补丁将创建一个真实的对象,我可以读取并检查它是否按预期将内容写入filestream,但我得到了:

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

我该如何解决这个问题?或者,如果内容在这个
MagicMock
对象中,我应该如何读取它?

首先,您应该模拟外部资源,而不是您自己的代码。 在这种情况下,
打开
。您可以使用库格式中的
mock\u open
测试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')
通过这种方式,您可以告诉python,在测试运行期间,假设存在一个新的
open
方法,并断言它的行为符合预期

当您使用补丁('my_logger.open_file_stream',return_value=StringIO.StringIO())作为f:
)执行
时,f是一个模拟对象,它将只包含您添加到其中的内容,即通过将return_value属性赋值或赋予它副作用


您可以根据自己的情况调整上述示例。
文件句柄
对象的行为将类似于任何其他
打开
对象,使用
写入
读取
读入
等方法,您可以根据需要进行测试。

应用
'w'
时,最后一行中的断言不起作用,但如果没有它,一切都可以工作。谢谢