【问题标题】:How to use mock_open with pickle.load如何将 mock_open 与 pickle.load 一起使用
【发布时间】:2020-03-19 16:39:39
【问题描述】:

我想对一个函数进行单元测试:

def load_pickle(path):
    with open(path, 'r') as of:
        return pickle.load(of)

我修改了我在 https://nickolaskraus.org/articles/how-to-mock-the-built-in-function-open/ 上找到的内容来实现我的单元测试

import pickle
from mock import mock_open

def test_load_pickle(self):
        read_data = pickle.dumps({'a': 1, 'b': 2, 'c': 3})
        mockOpen = mock_open(read_data=read_data)
        with patch('__builtin__.open', mockOpen):
            # 'testPath' is supposed to be just a string that doesn't correspond to any real path
            obj = load_pickle('testPath')
        self.assertEqual({'a': 1, 'b': 2, 'c': 3}, obj)

虽然当我将所有 pickle 更改为 json 时效果很好,但它不适用于 pickle,并且我有一个错误:KeyError: "(dp0\nS'a'\np1\nI1\nsS'c'\np2\nI3\nsS'b'\np3\nI2\ns."

问题在于pickle.load 部分不起作用。我在网上搜索并没有找到任何解决方案。您不知道如何调整我的代码以使用 mock_openpickle.load 吗? 谢谢!

PS:我正在使用python27(我知道这很糟糕但我的公司还没有迁移到python3)

编辑: 我的完整代码

import unittest
import pickle

from mock import mock_open, patch

class Class(object):
    def load_pickle(self, path):
        with open(path, 'rb') as of:
            return pickle.load(of)


class TestClass(unittest.TestCase):
    def test_load_pickle(self):
        read_data = pickle.dumps({'a': 1, 'b': 2, 'c': 3})
        mockOpen = mock_open(read_data=read_data)
        with patch('__builtin__.open', mockOpen):
            obj = Class().load_pickle('testPath')
        self.assertEqual({'a': 1, 'b': 2, 'c': 3}, obj)

完整的追溯:

Traceback (most recent call last):
  File "/home/lsoret/softwares/miniconda3/envs/py27/lib/python2.7/unittest/case.py", line 329, in run
    testMethod()
  File "/home/lsoret/code/qynapse/python/qia/tests/models/testtest.py", line 17, in test_load_pickle
    obj = Class().load_pickle('testPath')
  File "/home/lsoret/code/qynapse/python/qia/tests/models/testtest.py", line 9, in load_pickle
    return pickle.load(of)
  File "/home/lsoret/softwares/miniconda3/envs/py27/lib/python2.7/pickle.py", line 1384, in load
    return Unpickler(file).load()
  File "/home/lsoret/softwares/miniconda3/envs/py27/lib/python2.7/pickle.py", line 864, in load
    dispatch[key](self)
KeyError: "(dp0\nS'a'\np1\nI1\nsS'c'\np2\nI3\nsS'b'\np3\nI2\ns."

【问题讨论】:

  • 嗯,我觉得很好。我刚刚测试了它(放置一个测试类,你似乎使用unittest),测试通过了。能否请您展示整个源代码(完整的测试类)?
  • 我运行了完全相同的代码(带有一个测试类 arround)但它不起作用,我有一个 KeyError: "(dp0\nS'a'\np1\nI1\nsS'c'\np2\nI3\nsS'b'\np3\nI2\ns."。可能是因为我用的是Python2.7?
  • 我也使用了 Python 2.7。你能展示你完整的测试代码吗?
  • 我编辑了我的原始帖子,谢谢!
  • 嗯,对我来说很好用......你在什么系统上?我在 Windows 10 下使用 Python 2.7.16 进行了测试。

标签: python-2.7 mocking pickle python-unittest


【解决方案1】:

找到了!

这是我的mock 版本过时了......从2.0.0 变为3.0.5,现在它工作正常。 谢谢!

【讨论】:

    【解决方案2】:

    对于 python3,将 __builtin__.open 更改为 builtins.open 也可以:)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-09-12
      • 1970-01-01
      • 2021-01-02
      • 1970-01-01
      • 2023-03-13
      • 2014-09-25
      • 2016-01-30
      • 2015-12-13
      相关资源
      最近更新 更多