Я написал класс, который наследует класс многопроцессорности .Process(). В инициализации я устанавливаю некоторые параметры, один из них - это другой класс, который записывает в файл на моем жестком диске. Для модульного тестирования я хотел бы высмеять этот экземпляр класса, чтобы избежать записи в файл. Вот несколько минимальных примеров:Класс Python наследует многопроцессорность: издевается над одним из объектов класса
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()
Код, указанный выше, должен работать как есть. Однако, если я попытаюсь высмеять класс _some_class в классе MyProcess (= раскомментирование строки в основной функции) Я получаю ошибки. Интересно, что я получаю то же самое, если пытаюсь инициализировать self._some_class с функцией (например, заменить строку 13 в коде выше с помощью * self._some_class = lambda x: x/2 *). Поэтому я предполагаю, что есть некоторая проблема с копированием объектов в MyProcess при возникновении нового процесса. Это вызывает два вопроса:
- Может ли кто-нибудь пролить свет, почему невозможно инициализировать объект класса с помощью функции?
- Как я мог издеваться над одним из объектов класса MyProcess?
Я был бы очень признателен за любую помощь ...
EDIT 1 (больше информации о сообщениях об ошибках):
Если я раскомментировать строку в главной функции я получаю кучу ошибок, где я думаю, что должна быть соответствующая одна следующее:
pickle.PicklingError: не можете замариновать: это не тот же объект mock.Mock
EDIT 2 (нашел соответствующую информацию):
Я нашел следующее issue в коде Google, что, похоже, связано с моей проблемой. Действительно, изменение издеваются в основной функции к следующему делает код, исполняемый:
proc._some_class = mock.MagicMock()
proc._some_class.__class__ = mock.MagicMock
Однако то, что я был бы заинтересован в для тестирования следующий вызов: proc._some_class.some_method.called, который всегда False, несмотря на то, что метод, очевидно, был вызван. Я предполагаю, что это имеет какое-то отношение к обходному пути, о котором я говорил выше.
EDIT 3 (обходной путь основан на предложении JB.):
можно обойти эту проблему, вызвав запустить метод напрямую. Следующий код содержит основную функцию и показывает, как проверить функцию с помощью издевается:
if __name__ == '__main__':
proc = MyProcess()
proc._some_class = mock.MagicMock()
proc.run()
print(proc._some_class.sum.called)
... какие ошибки? – jonrsharpe
Я получаю полный список ошибок, но я бы предположил, что соответствующий должен быть: * pickle.PicklingError: не может pickle: это не тот же объект, что и mock.Mock * –
Chris
@Veedrac : done, я переместил информацию с моего комментария на исходный пост. – Chris