问题
I'm trying to test a function that I made that iterates through a list, and calls os.path.exists
for each item in the list. My test is passing the function a list of 2 objects. I need os.path.exists
to return True
for one of them and False
for the other. I have tried this:
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)
Using either but not both of line #1 and #2 give NameError: global name 'side_effect' is not defined
I found this question and modified my code like so:
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)
And this produces TypeError: 'module' object is not callable
.
I also tried switching these lines:
mockobj = mock(spec=os.path.exists)
mockobj.side_effect = side_effect
for this
mockobj = mock(spec=os.path)
mockobj.exists.side_effect = side_effect
and this
mockobj = mock(spec=os)
mockobj.path.exists.side_effect = side_effect
with the same error being produced. Can anyone point out what it is that I am doing wrong and what I can do to get this to work?
EDIT:
After posting my answer below I realised that my first bit of code actually works as well, I just needed m.side_effect = TestClass.side_effect
instead of m.side_effect = side_effect
.
回答1:
So after a bit more research and trial and error, with most of the examples here: http://www.voidspace.org.uk/python/mock/patch.html, I solved my problem.
import mock
import os
def side_effect(arg):
if arg == 1:
return True
else:
return False
class TestClass(unittest.TestCase):
patcher = mock.patch('os.path.exists')
mock_thing = patcher.start()
mock_thing.side_effect = side_effect
arg_list = [1, 2]
ret = test(arg_list)
self.assertItemsEqual([1], ret)
test
calls os.path.exist
for each item in arg_list
, and returns a list of all items that os.path.exist
returned True
for. This test now passes how I want it.
回答2:
you could have done self.side_effect
I believe. since the initial definition was not global, calling side_effect
looks inside the global scope
来源:https://stackoverflow.com/questions/21927057/mock-patch-os-path-exists-with-multiple-return-values