Я пытаюсь проверить функцию, которую я сделал, итерации через список, и вызывает os.path.exists
для каждого элемента в списке. Мой тест передает функцию список из двух объектов. Мне нужно os.path.exists
, чтобы вернуть True
для одного из них и False
для другого. Я попытался это:mock/patch os.path.exists с несколькими возвращаемыми значениями
import mock
import os
import unittest
class TestClass(unittest.TestCase):
values = {1 : True, 2 : False}
def side_effect(arg):
return values[arg]
def testFunction(self):
with mock.patch('os.path.exists') as m:
m.return_value = side_effect # 1
m.side_effect = side_effect # 2
arglist = [1, 2]
ret = test(argList)
Использование любой, но не оба линии # 1 и # 2 дают NameError: global name 'side_effect' is not defined
Я нашел этот question и изменил мой код следующим образом:
import mock
import os
class TestClass(unittest.TestCase):
values = {1 : True, 2 : False}
def side_effect(arg):
return values[arg]
def testFunction(self):
mockobj = mock(spec=os.path.exists)
mockobj.side_effect = side_effect
arglist = [1, 2]
ret = test(argList)
И это производит TypeError: 'module' object is not callable
. Я также попытался переключения эти строки:
mockobj = mock(spec=os.path.exists)
mockobj.side_effect = side_effect
для этого
mockobj = mock(spec=os.path)
mockobj.exists.side_effect = side_effect
и это
mockobj = mock(spec=os)
mockobj.path.exists.side_effect = side_effect
с той же ошибкой производится. Может ли кто-нибудь указать, что я делаю неправильно, и что я могу сделать, чтобы заставить это работать?
EDIT: После размещения моего ответа ниже, я понял, что мой первый бит коды на самом деле работает хорошо, мне просто нужно m.side_effect = TestClass.side_effect
вместо m.side_effect = side_effect
.
А что, если функция имеет тот же аргумент для обоих вызовов? – hithwen
Что значит? Если 'os.path.exists' передается 1 для обоих вызовов? Затем он вернет True, потому что это то, что говорит побочный эффект. Но он не будет передан один и тот же аргумент дважды, потому что функция 'test' выполняет итерацию через' arg_list' и вызывает 'os.path.exists' для каждого элемента в списке. Поэтому, пока оба элемента в списке не '1', он будет работать так, как ожидалось. –
Я имел в виду, если я хочу дважды вызвать os.path.exists с тем же аргументом и вернуть сначала False, а затем True. Я выяснил, как это сделать, определяя функцию, которая будет подсчитывать, сколько раз было вызвано и возвращало разные значения и использовало ее как side_effect. – hithwen