【问题标题】:PicklingError when using mock to check function is called使用模拟检查函数时调用 PicklingError
【发布时间】:2020-03-11 00:49:14
【问题描述】:

我在测试使用mock 调用方法时遇到问题——举个简单的例子,假设方法是os.getcwd。我想测试我自己的函数pickle_wdir 是否按预期调用os.getcwd。但是,我正在测试的函数腌制os.getcwd 返回的值,这会导致错误。

这是一个重现错误的简单示例。

os_ex.py:

import os
import pickle

def pickle_wdir(filename):
    dir = os.getcwd()
    with open(filename, 'wb') as handle:
        pickle.dump(dir, handle)

test_os_ex.py:

from unittest import TestCase
from unittest.mock import patch
from os_ex import pickle_wdir


class TestPickleWdir(TestCase):
    def test_os_called(self):
        fname = 'dir.pickle'
        with patch('os_ex.os') as mocked_obj:
            pickle_wdir(fname)
            mocked_obj.getcwd.assert_called()

返回的错误信息是

_pickle.PicklingError: Can't pickle <class 'unittest.mock.MagicMock'>: it's not the same object as unittest.mock.MagicMock.

如何在没有得到 PicklingError 的情况下测试 os.getcwd 是否被调用?

【问题讨论】:

    标签: python pickle python-unittest python-unittest.mock


    【解决方案1】:

    您需要模拟 os.getcwd()open()pickle.dump() 方法。您可以使用unittest.mock.patch 作为上下文管理器来执行此操作。

    例如

    os_ex.py:

    import os
    import pickle
    
    
    def pickle_wdir(filename):
        dir = os.getcwd()
        with open(filename, 'wb') as handle:
            pickle.dump(dir, handle)
    

    test_os_ex.py:

    import unittest
    from unittest.mock import patch, mock_open
    from os_ex import pickle_wdir
    
    
    class TestOsEx(unittest.TestCase):
        def test_pickle_wdir(self):
            fname = 'dir.pickle'
            m = mock_open(read_data='mocked data')
            with patch('os_ex.os') as mocked_obj, patch('builtins.open', m) as mocked_open, patch('pickle.dump') as mocked_dump:
                mocked_obj.getcwd.return_value = '/root'
                pickle_wdir(fname)
                mocked_obj.getcwd.assert_called()
                m.assert_called_with(fname, 'wb')
                handle = mocked_open()
                mocked_dump.assert_called_with('/root', handle)
    
    
    if __name__ == '__main__':
        unittest.main()
    

    100% 覆盖率的单元测试结果:

    .
    ----------------------------------------------------------------------
    Ran 1 test in 0.012s
    
    OK
    Name                                       Stmts   Miss  Cover   Missing
    ------------------------------------------------------------------------
    src/stackoverflow/60627827/os_ex.py            6      0   100%
    src/stackoverflow/60627827/test_os_ex.py      17      0   100%
    ------------------------------------------------------------------------
    TOTAL                                         23      0   100%
    

    【讨论】:

      猜你喜欢
      • 2020-03-08
      • 2022-08-23
      • 1970-01-01
      • 1970-01-01
      • 2021-08-28
      • 2020-05-08
      • 2017-01-21
      • 1970-01-01
      • 2019-07-22
      相关资源
      最近更新 更多