I would like to call the function that is mocked before the mock is called. What is the best way to do this?
main.py
import logging
import sys
import sys
from PyQt6.QtWidgets import QApplication, QMainWindow, QPushButton
class MainWindow(QMainWindow):
def __init__(self, app: QApplication):
super().__init__()
self.app = app
self.resize(330, 200)
self.setWindowTitle("Window 1")
self.button = QPushButton("Button")
self.setCentralWidget(self.button)
self.message_printed = False
def button_clicked() -> None:
self.display_message("Hello, world!")
self.button.clicked.connect(button_clicked)
def display_message(self, msg: str) -> None:
logging.info(f"Message: {msg}")
# Some complex code here...
self.message_printed = True
def main():
logging.basicConfig(level=logging.INFO)
app = QApplication(sys.argv)
window = MainWindow(app)
window.show()
app.exec()
if __name__ == '__main__':
logging.basicConfig(level=logging.INFO)
main()
This test does not pass, since the mock is called instead of the mocked function (not after):
test_main.py:
from PyQt6.QtCore import Qt
from main import MainWindow
def test_message(qtbot, qapp, mocker):
window = MainWindow(app=qapp)
qtbot.addWidget(window)
window.show()
with qtbot.waitCallback() as callback:
mocker.patch.object(window, "display_message", callback)
qtbot.mouseClick(window.button, Qt.MouseButton.LeftButton)
assert window.message_printed
However, the following test works but I would like to know if there is simpler (more elegant) way to do this:
test_main2.py:
from PyQt6.QtCore import Qt
from main import MainWindow
def test_message(qtbot, qapp, mocker):
window = MainWindow(app=qapp)
qtbot.addWidget(window)
window.show()
with qtbot.waitCallback() as callback:
def gen_wrapper():
original_method = window.display_message
def wrapper(*args, **kwargs):
original_method(*args, **kwargs)
callback(*args, **kwargs)
return wrapper
wrapper = gen_wrapper()
mocker.patch.object(window, "display_message", wrapper)
qtbot.mouseClick(window.button, Qt.MouseButton.LeftButton)
assert window.message_printed