我试图模仿在我的类的方法中使用的开放函数。 我找到了这个线程How do I mock an open used in a with statement (using the Mock framework in Python)?,但无法解决我的问题。unittest文档还显示了一个解决方案,它也没有模拟我的open https://docs.python.org/3/library/unittest.mock-examples.html#patch-decorators
这是使用open函数的方法的类:
#__init.py__
import json
class MyClass:
def save_data_to_file(self, data):
with open('/tmp/data.json', 'w') as file:
json.dump(data, file)
...
mc = MyClass()
现在我找到了一个不同的解决方案。这是我的测试:
#save_to_file_test.py
from mymodule import MyClass
from mock import mock_open, patch
import ast
class SaveToFileTest(unittest.TestCase):
def setUp(self):
self.mc = MyClass()
self.data = [
{'id': 5414470, 'name': 'peter'},
{'id': 5414472, 'name': 'tom'},
{'id': 5414232, 'name': 'pit'},
]
def test_save_data_to_file(self):
m = mock_open()
with patch('mymodule.open', m, create=True):
self.mc.save_data_to_file(self.data)
string = ''
for call in m.return_value.write.mock_calls:
string += (call[1][0])
list = ast.literal_eval(string)
assertEquals = (list, self.data)
我不确定这是否是测试应该写入文件的内容的最佳方法。 当我测试mock_调用时(call_args_list相同),这是传递给文件句柄的参数。 欢迎提出任何建议、改进和建议。
TL;博士
问题的核心是,为了能够正确地测试将要写入文件的数据,您应该同时模拟
json.dump
。实际上,在对测试方法进行一些重要的调整之前,我很难运行您的代码。builtins.open
而不是mymmodule.open
模拟m.return_value.__enter__.write
,但是您实际上是从json.dump调用write,这是将调用write的地方。(下面详细介绍建议的解决方案)json.dump
以简单地验证它是用您的数据调用的简而言之,针对上述问题,该方法可以重新编写为:
下面所有这些的详细信息
详细说明
为了关注我在您的代码中看到的问题,我强烈建议您做的第一件事,因为
open
是一个内置的,是模仿内置的,而且,您可以通过使用new_callable
和as
为自己保存一行代码,因此您可以简单地执行以下操作:下一个问题,我看到你的代码,因为我运行这个问题,直到我真正作出以下调整时,你开始循环你的调用:
要剖析这一点,您必须记住的是,您的方法使用的是上下文管理器。在使用上下文管理器时,编写工作实际上将在
__enter__
方法中完成。因此,从return_value
的m
中,您希望获得__enter__
的返回值。然而,这就把我们带到了问题的核心,你想测试什么。由于
json.dump
在写入文件时是如何工作的,因此在检查代码后进行写入的mock_calls
实际上如下所示:这可不好玩。所以,这就引出了下一个可以尝试的解决方案:Mock
json.dump
。你不应该测试json.dump,你应该测试用正确的参数调用它。话虽如此,你也可以用类似的方式模仿你的嘲笑,然后做这样的事情:
现在,有了它,您可以大大简化您的测试代码,简单地验证用您正在测试的数据调用该方法。所以,有了这个,当你把它放在一起的时候,你会得到这样的东西:
如果您对进一步的重构感兴趣,以使测试方法更干净一些,您还可以将修补设置为decorator,使代码在方法中更干净:
在这里,检查是您最好的朋友,查看在哪些步骤调用了哪些方法,以进一步帮助测试。祝你好运。
相关问题 更多 >
编程相关推荐