【问题标题】:How to check what was written to a mock_open() fake file?如何检查写入 mock_open() 假文件的内容?
【发布时间】:2022-01-26 09:39:54
【问题描述】:

我有一个生产功能,可以读取一个文件,并且在某些情况下还写入(不止一次)另一个文件(带有详细的错误输出)。

我能够模拟文件读取并在单元测试中给出特定的文件内容。但我不知道如何测试写入第二个文件的内容,该文件也通过mock_open() 模拟。

重要的一点是,我对在单元测试时将真实文件写入文件系统不感兴趣。

这是生产代码:

import pathlib

def my_prod_code(fp):
    with fp.open('r') as if:
        result = if.read()

    with fp.with_suffix('.error.out').open('w') as of:
        of.write(f'Read {result}.')
        of.write('FIN.')

    return result

那是单元测试

import unittest
from unittest import mock
import pathlib

class MyTest(unittest.TestCase):
    def test_foobar(self, mock_unlink):
        opener = mock.mock_open(read_data='foobar')

        with mock.patch('pathlib.Path.open', opener):
            result = my_prod_code(pathlib.Path('file.in'))
            self.assertEqual(result, 'foobar')
            
            # Want to check for the written content also

【问题讨论】:

    标签: python unit-testing mocking


    【解决方案1】:

    没有内置的方法可以做到这一点,因此您要么必须在模拟中添加自己的处理,要么使用一些伪造文件系统的包。

    添加您自己的处理意味着实现您自己的write,例如像这样:

    class MockWriter:
        """Collect all written data."""
        def __init__(self):
            self.contents = ''
    
        def write(self, data):
            self.contents += data
    
    class MyTest(unittest.TestCase):
        def test_foobar(self):
            opener = mock.mock_open(read_data='foobar')
            writer = MockWriter()
            # replace the write method in the mock with your own
            opener.return_value.write = writer.write
            with mock.patch('pathlib.Path.open', opener) as f:
                result = my_prod_code(pathlib.Path('file.in'))
                self.assertEqual(result, 'foobar')
                self.assertEqual(writer.contents, 'Read foobar.FIN.')
    

    另一种可能性是使用像pyfakefs这样的假文件系统:

    from pyfakefs.fake_filesystem_unittest import TestCase
    
    class MyTest(TestCase):
        def setUp(self):
            self.setUpPyfakefs()
    
        def test_foobar(self):
            self.fs.create_file('file.in', contents='foobar')
            result = my_prod_code(pathlib.Path('file.in'))
            self.assertEqual(result, 'foobar')
            path = pathlib.Path('file.error.out')
            self.assertEqual(path.read_text(), 'Read foobar.FIN.')
    

    这样,您不必自己进行模拟,并且可以使用标准文件系统函数,但缺点是您需要一个额外的包,这会产生一些测试开销。

    免责声明:
    我是 pyfakefs 的贡献者。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 2015-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-30
      相关资源
      最近更新 更多