I have a recursive function living in a module called test_module
import requests
def send_msg(msg, retries=0):
try:
# send the message here, e.g. a http request
response = requests.get("http://www.doesnotexist98734.com")
# if url does not exist raise an exception
except Exception as e:
if retries == 0:
raise e
else:
return send_msg(msg, retries=retries-1)
My question is how can I write a unittest that checks the send_msg
function is called n times when I set retries = n. I was playing around with the mock module (I'm using python 2.7) and I think I want something a bit like this,
import mock, unittest
class MyUnitTest(unittest.TestCase):
@mock.patch('test_module.send_msg')
def test_send_msg_tries_n_times(self, mock_send_msg):
with self.assertRaises(Exception):
mock_send_msg("hello", retries=3)
self.assertEqual(mock_send_msg.call_count, 4) # initial call + 3 retries
However since I have mocked the function it won't call the real function so I don't get an exception nor does it call itself recursively...
You can't mock the function under test. You want to test for expected results, not if the function used recursion correctly.
Mock the request.get()
call, and have it always produce an exception. Then count how often your mock was called.
@mock.patch('requests.get')
def test_send_msg_tries_n_times(self, req_get_mock):
req_get_mock.side_effect = Exception
with self.assertRaises(Exception):
send_msg("hello", retries=3)
self.assertEqual(req_get_mock.call_count, 4) # 1 initial call + 3 retries
If in future you want to avoid using recursion and want to use iteration instead, your test still will work as it validates the behaviour, not the specific implementation. You can safely refactor the function-under-test.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With