These answers seem to have missed something.
In my case I had a simple file with some constants at the top, like this:
LIB_DIR_PATH_STR = 'some_path_to_module'
After this I have a method during which I add this library to sys.path
prior to importing it:
def main():
...
sys.path.append(LIB_DIR_PATH_STR)
... but what I wanted to do in testing is to mock LIB_DIR_PATH_STR, so that it points to a non-existent path, i.e. for error-handling. Here we're not talking about mocking any classes or even methods in a script.
However, it turns out that it is possible (where my_script
has previously been imported):
with mock.patch.object(my_script, 'LIB_DIR_PATH_STR', new_callable=mock.PropertyMock(return_value=non_existent_dir_path_str)):
my_script.main()
... i.e. PropertyMock
can be instantiated with a return_value
of its own. The is not the same as specifying the return_value
for a patch in which a PropertyMock
is participating (the class of the patch will then be Mock
or maybe MagicMock
). The latter approach simply won't work for this simple "replace a string with another" type of mock: pytest will complain "expected string but got Mock".
My specific example is tangential to the question (class attributes), to show how it's done. But it can be used with class attributes too...