如何修补方法io.RawIOBase.read用unittest?

2024-05-23 16:56:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我最近了解了unittest.monkey.patch及其变体,我想用它来对文件读取函数的原子性进行单元测试。然而,这个补丁似乎没有任何效果。在

这是我的设置。审查的方法大致如下(简写):

#local_storage.py

def read(uri):
    with open(path, "rb") as file_handle:
        result = file_handle.read()
    return result

以及执行单元测试的模块(也被删节):

^{pr2}$

这样,修补程序应该确保每次您尝试读取它时,文件在实际读取之前和之后都会被修改,就好像它同时发生一样,从而测试读取的原子性。在

单元测试目前成功了,但是我用print语句验证了patch函数实际上没有被调用,因此文件永远不会得到额外的写入(它只是说“test”)。我还特意将代码修改为非原子代码。在

所以我的问题是:如何修补本地存储模块中IO句柄的read函数?我在其他地方读到,人们倾向于替换open()函数来返回一个StringIO之类的东西,但我不认为这能解决这个问题。在

我需要支持python3.4及更高版本。在


Tags: 文件函数代码read变体单元测试unittestresult
1条回答
网友
1楼 · 发布于 2024-05-23 16:56:21

我终于自己找到了解决办法。在

问题是mock不能模仿用C编写的对象的任何方法,其中之一就是我遇到的RawIOBase。在

因此,解决方案实际上是模拟open,以返回{}的包装器。我无法让mock为我生成一个包装器,所以我自己实现了它。在

有一个预定义的文件被认为是“不安全的”。每次调用包装器时,包装器都会写入此“不安全”文件。这允许测试文件写入的原子性,因为它会在写入时向不安全的文件写入额外的内容。我的实现通过写入一个临时(“安全”)文件,然后将该文件移动到目标文件上来防止这种情况。在

包装器对于read函数有一个特殊情况,因为要正确地测试原子性,它需要在读取期间写入文件。因此,它首先读取文件的一半,然后停止并写入一些内容,然后继续读取。这个解决方案现在是半硬编码的(有多远是一半),但我会找到改进的方法。在

你可以在这里看到我的解决方案:https://github.com/Ghostkeeper/Luna/blob/0e88841d19737fb1f4606917f86e3de9b5b9f29b/plugins/storage/localstorage/test/test_local_storage.py

相关问题 更多 >