I have a main.py file which includes WindoMgr class, xvfb as a class attibute and two classmethods: _cleanup_lock_file and func_to_test. I only have problem with testing else block, which gets triggered when cls.xvfb is None. The else block returns default value of b which is 1.
#main.py
class WindowMgr:
xvfb = None
@classmethod
def _cleanup_lock_file(cls):
return True
@classmethod
def func_to_test(cls):
b = 1
if cls.xvfb is not None:
print(cls.xvfb) #<MagicMock name='xvfb' id='61908568'>
try:
cls.xvfb.terminate()
b = 2
except Exception:
b = 1 2
finally:
cls._cleanup_lock_file()
else:
return b
return b
Now, in the test_main.py file, I have patched the xvfb
to mock cls.xvfb.terminate()
in try block, but I want cls.xvfb
to be None for the else block to be triggered. I have tried something like xvfb = None
or xvfb.return_value = None
. But the else block doesn't get triggered as printing cls.xvfb
shows it as a MagickMock
object as commented out in the code. The WindowMgr.func_to_test()
return value is 2 and not 1. It should return default value of b as 1.
How do I set cls.xvfb
mock object as None
? Any help would be appreciated.
#test_main.py
from main import WindowMgr
def test_main_func(mocker):
xvfb = mocker.patch.object(WindowMgr, 'xvfb')
# To test the else block
# xvfb = None -----> doesn't work
# xvfb.return_value = None ----> doesn't work
assert WindowMgr.func_to_test() == 1 # AssertionError: assert 2 == 1
CodePudding user response:
The problem is that setting xvbf
does only reassign the local variable, not the mocked variable (this is just normal Python behavior). Setting the return_value
does not work, because xvbf
is not a callable. However, if you use a property mock instead of a regular mock, it will behave as if it were a callable, and the value can be set via return_value
:
def test_main_func(mocker):
xvfb = mocker.patch.object(WindowMgr, "xvfb",
new_callable=mocker.PropertyMock)
xvfb.return_value = None
assert WindowMgr.func_to_test() == 1
(you can access PropertyMock
directly from mocker
as a convenience)
Even if xvbf
is a class variable and not a property, it behaves like a property from the perspective of a mock and this will work.