gpt4 book ai didi

Python 类继承 multiprocessing : mocking one of the class objects

转载 作者:太空宇宙 更新时间:2023-11-04 03:41:47 25 4
gpt4 key购买 nike

我编写了一个继承multiprocessing.Process() 类的类。在初始化中我设置了一些参数,其中一个是另一个类,它写入我硬盘上的某个文件。出于单元测试的目的,我想模拟此类实例以避免实际写入某些文件。这是一些最小的例子:

import mock
import time
import multiprocessing as mp
import numpy as np

class MyProcess(mp.Process):

def __init__(self):
super(MyProcess, self).__init__()

# the original code would create some instance of a file manipulation
# class here:
self._some_class = np.zeros(100)

def run(self):

# the following line would actually write to some file in the original
# code:
self._some_class.sum()

for ii in range(10):
print(str(ii))
time.sleep(.01)

if __name__ == '__main__':

proc = MyProcess()
# proc._some_class = mock.Mock()

proc.start()
proc.join()

上面的代码应该按原样运行。但是,如果我尝试模拟类 MyProcess 中的类 _some_class (= 取消注释 main 函数中的行),我会得到错误。有趣的是,如果我尝试使用函数初始化 self._some_class(例如,将上面代码中的第 13 行替换为 *self._some_class = lambda x: x/2 *),我会得到完全相同的错误。所以我的猜测是,在生成新进程时复制 MyProcess 中的对象存在一些问题。这就提出了两个问题:

  • 有人可以阐明为什么不能用函数初始化类对象吗?
  • 如何模拟 MyProcess 的类对象之一?

我真的很感激任何帮助...

编辑 1(有关错误消息的更多信息):

如果我取消注释 main 函数中的行,我会得到一堆错误,我认为以下应该是相关的错误:

pickle.PicklingError: Can't pickle : 它与 mock.Mock 不是同一个对象

编辑 2(找到一些相关信息):

我找到了以下 issue在谷歌代码上,这似乎与我的问题有关。实际上,将 main 函数中的 mock 更改为以下内容会使代码可执行:

proc._some_class = mock.MagicMock()
proc._some_class.__class__ = mock.MagicMock

但是,我对测试感兴趣的是以下调用:proc._some_class.some_method.called,它始终是 False,尽管该方法显然已经被调用了。我想这与我上面提到的解决方法有关。

编辑 3(基于 jb. 的建议的解决方法):

可以通过直接调用run 方法来解决这个问题。以下代码包含主要功能,并展示了如何使用模拟测试该功能:

if __name__ == '__main__':

proc = MyProcess()
proc._some_class = mock.MagicMock()
proc.run()

print(proc._some_class.sum.called)

最佳答案

虽然这不能直接解决您的问题,但请考虑以下方法。从 Process 对象继承可能会使实现更容易,但是(正如您所指出的)在进行单元测试时可能会非常困难。

如果将 run 函数作为参数传递给 Process 实例会容易得多,这样您就可以单独测试 run 函数多处理环境。如果您需要在另一个进程中测试 run 行为,只需创建一个可调用对象,并在其中模拟适当的东西。

沿线的东西:

from multiprocessing import Process

def f(name):
print 'hello', name

if __name__ == '__main__':
p = Process(target=f, args=('bob',))
p.start()
p.join()

如果你想坚持你的设计,你不应该使用 MagicMock,python 多处理接口(interface)依赖于 pickling ,模拟库和酸洗不去well together .只需编写自己的模拟类即可。

关于Python 类继承 multiprocessing : mocking one of the class objects,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26094560/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com