Reputation: 5729
Hello I have the following code;
I am trying to test the load function inside file_a; download is function in an external module I imported
file_a.py
from foo import download
class Bar()
__init__(self, arg_1):
self.var = arg_1
def load(self):
if self.var == "latest_lib":
download("latest_lib")
I wrote the test like
test.py
@patch(file_a.download)
def test_download():
import file_a
bar = file_a.Bar("latest_lib")
bar.load()
file_a.download.assert_called()
But it seems like the bar object is not calling the mock download rather the imported download. How can I fix this problem and make my test pass?
Upvotes: 3
Views: 5804
Reputation: 738
I tried to use your own code to see where was wrong. There were some syntax errors which doesn't really matter, but the main issue is that you should pass strings to patch
to make it work.
Here's my modification to your code that made it all happen:
# file_a.py
from pprint import pprint as pp
class Bar():
def __init__(self, arg_1):
self.var = arg_1
def load(self):
if self.var == "latest_lib":
pp("latest_lib")
And:
# test_file_a.py
import unittest
from unittest.mock import patch
class TestStringMethods(unittest.TestCase):
@patch("file_a.pp")
def test_download(self, pp):
import file_a
bar = file_a.Bar("latest_lib")
bar.load()
pp.assert_called()
if __name__ == "__main__":
unittest.main()
NOTES:
patch
to make it mock the object in runtime.unittest
standard library, but you don't have to do the same if you're using pytest
.Also one final note from the official doc:
The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.
Upvotes: 3
Reputation: 929
I think you are missing the mock setup:
@patch("foo.download")
def test_download(mock_download):
from file_a import Bar
Bar("latest_lib").load()
mock_download.assert_called()
Upvotes: 0