Reputation: 153
I have a file, main.py, which contains one method, main():
from grab_api_tokens import GrabApiTokens
def main()
grab_api_tokens = GrabApiTokens(site_one, site_two)
site_one_token = grab_api_tokens.login_to_site_one
site_two_token = grab_api_tokens.login_to_site_two
When trying to test this, I'm using:
import unittest
from unittest.mock import patch, Mock
import main
class TestMain(unittest.TestCase):
@patch('main.grab_apitokens.GrabApiTokens.login_to_site_two')
@patch('main.grab_apitokens.GrabApiTokens.login_to_site_one')
@patch('main.grab_apitokens.GrabApiTokens')
def test_main(self, mock_grab_api_tokens, mock_login_to_site_one, mock_login_to_site_two):
mock_grab_api_tokens = Mock(ok=True)
mock_login_to_site_one.return_value = "fake_token_one"
mock_login_to_site_two.return_value = "fake_token_two"
main.main()
self.assertTrue(mock_grab_api_tokens.called)
the problem is that no matter how I change the @patch, I can't seem to get pycharm to recognize the mocked class. Calling main() just calls the plain main method, its not patching over the values I'm specifying. I can't see where I've gone wrong after reading the unittest documentation.
Upvotes: 3
Views: 874
Reputation: 102257
The target you try to patch is not correct. Besides, you don't need to patch the properties of the GrabApiTokens
class. You can patch the GrabApiTokens
class and assign the fake data to the properties of its instance directly.
E.g.
main.py
:
from grab_api_tokens import GrabApiTokens
def main():
site_one = '123'
site_two = '456'
grab_api_tokens = GrabApiTokens(site_one, site_two)
site_one_token = grab_api_tokens.login_to_site_one
site_two_token = grab_api_tokens.login_to_site_two
print('site_one_token: ', site_one_token)
print('site_two_token: ', site_two_token)
grab_api_tokens.py
:
class GrabApiTokens():
def __init__(self, site_one, site_two) -> None:
self.login_to_site_one = site_one
self.login_to_site_two = site_two
test_main.py
:
import unittest
from unittest.mock import patch, Mock
import main
class TestMain(unittest.TestCase):
@patch('main.GrabApiTokens')
def test_main(self, mock_grab_api_tokens):
mock_instance = mock_grab_api_tokens.return_value
mock_instance.login_to_site_one = "fake_token_one"
mock_instance.login_to_site_two = "fake_token_two"
main.main()
self.assertTrue(mock_grab_api_tokens.called)
if __name__ == '__main__':
unittest.main()
test result:
⚡ coverage run /Users/dulin/workspace/github.com/mrdulin/python-codelab/src/stackoverflow/66641783/test_main.py && coverage report -m --include="src/*"
site_one_token: fake_token_one
site_two_token: fake_token_two
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK
Name Stmts Miss Cover Missing
-----------------------------------------------------------------------------
src/stackoverflow/66641783/grab_api_tokens.py 4 2 50% 3-4
src/stackoverflow/66641783/main.py 9 0 100%
src/stackoverflow/66641783/test_main.py 13 0 100%
-----------------------------------------------------------------------------
TOTAL
Upvotes: 1