Issue with Mocking send_request()
in Unit Tests
I’m having trouble with mocking the send_request()
function in my tests. Despite using patch
, the original send_request()
function is being called, and the mock isn’t applied. Here’s the relevant output and code:
Output:
Send_click
send_request mock: <function send_request at 0x7f9c2146de40>
send request
Code:
logic.py
def send_request(manager, action_method, url, data=None, params=None, headers=None):
print("send request")
test_ui.py
from ..ui import UserInterface
from unittest.mock import patch, Mock
@patch("ui.send_request")
def test_send_request(mock_send_request, qtbot):
ui = UserInterface()
ui.get_request_data = Mock()
data = QByteArray(data_str_create.encode("utf-8"))
action_method, url, data = ACTIONS_METHODS.POST, QUrl("https://example.com/api"), data
ui.get_request_data.return_value = action_method, url, data
ui.send_click()
mock_send_request.assert_called_once()
Issue:
send_request()
is not mocked; the original function is being executed. Proven bysend request
in the output andfunction
type in the output.- The
AssertionError
in the last line of the test indicates that the mock was not applied.
How send_request()
is used:
ui.py
from logic import handle_response, send_request
class UserInterface(QWidget):
# other methods
def get_request_data(self):
action_method = self.combo_box.currentText()
json_dict = json.loads(
self.body.toPlainText().encode("utf-8").decode("unicode_escape")
)
json_data = json.dumps(json_dict).encode("utf-8")
data = QByteArray(json_data)
url = QUrl(self.url.text())
return action_method, url, data
def send_click(self):
print("Send_click")
print(f"send_request mock: {send_request}")
send_request(self.rest_manager, *self.get_request_data())
Can someone help figure out why the send_request()
function is not being mocked as expected?
1
The structure of ypur project in my system
I have created in my system the following structure of your project:
project
|- ui.py
|- logic.py
|- test
|- test_ui.py
The code of the file test_ui.py
I have modified your test_ui.py
file as following:
import unittest
from unittest.mock import patch, Mock
import sys
sys.path.append("/path/to/project")
from ui import UserInterface
class MyTestCase(unittest.TestCase):
@patch("ui.send_request")
def test_send_request(self, qtbot):
ui = UserInterface()
ui.get_request_data = Mock()
#data = QByteArray(data_str_create.encode("utf-8"))
#action_method, url, data = ACTIONS_METHODS.POST, QUrl("https://example.com/api"), data
#ui.get_request_data.return_value = action_method, url, data
ui.get_request_data.return_value = "action_method", "url", "data"
ui.send_click()
qtbot.assert_called_once()
if __name__ == '__main__':
unittest.main()
The changes to your test file
I have defined test_send_request()
as a method of MyTestCase
class that is a subclass of MyTestCase
.
The most important changes to your test_send_request()
method are:
- set
ui.get_request_data.return_value
to"action_method", "url", "data"
to simplify the execution (I don’t have the code ofQWidget
,ACTIONS_METHODS
and so on) - change the instruction
mock_send_request.assert_called_once()
toqtbot.assert_called_once()
- I have modified your import as following:
sys.path.append("/path/to/project")
from ui import UserInterface
The output of the test execution
In this way the output of the execution is:
Send_click
send_request mock: <MagicMock name='send_request' id='140010776190368'>
In the output misses the string:
send request
as you wish and the test is successfully pass.