我最近了解了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及更高版本。在
我终于自己找到了解决办法。在
问题是
mock
不能模仿用C编写的对象的任何方法,其中之一就是我遇到的RawIOBase
。在因此,解决方案实际上是模拟}的包装器。我无法让
open
,以返回{mock
为我生成一个包装器,所以我自己实现了它。在有一个预定义的文件被认为是“不安全的”。每次调用包装器时,包装器都会写入此“不安全”文件。这允许测试文件写入的原子性,因为它会在写入时向不安全的文件写入额外的内容。我的实现通过写入一个临时(“安全”)文件,然后将该文件移动到目标文件上来防止这种情况。在
包装器对于
read
函数有一个特殊情况,因为要正确地测试原子性,它需要在读取期间写入文件。因此,它首先读取文件的一半,然后停止并写入一些内容,然后继续读取。这个解决方案现在是半硬编码的(有多远是一半),但我会找到改进的方法。在你可以在这里看到我的解决方案:https://github.com/Ghostkeeper/Luna/blob/0e88841d19737fb1f4606917f86e3de9b5b9f29b/plugins/storage/localstorage/test/test_local_storage.py
相关问题 更多 >
编程相关推荐