Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.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 使用mock.patch和mock_open模拟包含JSON数据的文件_Python_Python 3.x_Python Unittest_Python Unittest.mock - Fatal编程技术网

Python 使用mock.patch和mock_open模拟包含JSON数据的文件

Python 使用mock.patch和mock_open模拟包含JSON数据的文件,python,python-3.x,python-unittest,python-unittest.mock,Python,Python 3.x,Python Unittest,Python Unittest.mock,我正在尝试测试一个方法,该方法需要在Python3.6中使用json.load。 在几次尝试之后,我尝试“正常”运行测试(使用CLI中常用的unittest.main()),并在iPython REPL中运行测试 具有以下功能(为了示例的目的而简化) 通过以下测试: class test_loading_metadata(unittest2.TestCase): @patch('builtins.open', new_callable=mock_open(read_data='{"dis

我正在尝试测试一个方法,该方法需要在Python3.6中使用
json.load
。 在几次尝试之后,我尝试“正常”运行测试(使用CLI中常用的unittest.main()),并在iPython REPL中运行测试

具有以下功能(为了示例的目的而简化)

通过以下测试:

class test_loading_metadata(unittest2.TestCase):
    @patch('builtins.open', new_callable=mock_open(read_data='{"disabled":True}'))
    def test_load_metadata_with_disabled(self, filemock):
        result = load_metadata("john")
        self.assertEqual(result,{"disabled":True})
        filemock.assert_called_with("john.json")
执行测试文件的结果会让人心碎:

TypeError: the JSON object must be str, bytes or bytearray, not 'MagicMock'
在命令行中执行相同的操作时,会给出一个成功的结果

我尝试了几种方法(以装饰者的身份使用
进行修补),但我能想到的唯一一件事是
单元测试
库本身,以及它可能会干扰mock和patch的任何操作

还检查了virtualenv和ipython中的python版本,即
json
库的版本

我想知道为什么看起来相同的代码在一个地方起作用 在另一种情况下不起作用。 或者至少有一个指向正确方向的指针来理解为什么会发生这种情况。

只是调用
fh.read()
,但
fh
不是
mock_open()
对象。它是一个
mock_open()()
对象,因为在修补创建替换对象之前会调用
new_callable

>>> from unittest.mock import patch, mock_open
>>> with patch('builtins.open', new_callable=mock_open(read_data='{"disabled":True}')) as filemock:
...     with open("john.json") as fh:
...         print(fh.read())
...
<MagicMock name='open()().__enter__().read()' id='4420799600'>
当用作
open()
函数时,此时可以对其调用
.read()

>>> with patch('builtins.open', mock_open(read_data='{"disabled":True}')) as filemock:
...     with open("john.json") as fh:
...         print(fh.read())
...
{"disabled":True}

new
参数是修补时将替换原始参数的对象。如果保留默认值,则使用
new\u callable()
。你不想在这里看到
new\u callable()。你在说什么功能?这门课是单元测试吗?这里的问题与其他方法或函数无关。如果您有一个可以工作的测试函数,那么您忘记了共享它,并且您可能没有使用
new\u callable
,或者将可调用函数包装在lambda中。它不会是完全相同的
补丁(…)
配置。我忘了共享测试功能。对不起。我又检查了一遍,你是对的,这是一个稍微不同的补丁配置。谢谢你对问题的更正。我太累了,连笔头都写不直了。到了该睡觉的时候了,以后你的工作效率会更高。:-)
@patch('builtins.open', mock_open(read_data='{"disabled":True}'))
def test_load_metadata_with_disabled(self, filemock):
>>> with patch('builtins.open', mock_open(read_data='{"disabled":True}')) as filemock:
...     with open("john.json") as fh:
...         print(fh.read())
...
{"disabled":True}