声明`mocked_function.call`为单元测试

时间:2019-08-14 16:01:10

标签: python qt unit-testing mocking pyside

我希望对PySide UI实施单元测试,但无法弄清楚如何正确断言连接到ui元素的函数是否被调用。

到目前为止,我已经尝试了不同的方式来导入要编写测试的模块。模拟功能的不同方式

../ app / ui.py

import sys

from PySide.QtGui import *
from PySide.QtCore import *

def btn1_callback():
    print("1")

class Window(QWidget):
    def __init__(self, *args, **kwargs):
        super(Window, self).__init__(*args, **kwargs)

        layout = QVBoxLayout()

        self.btn1 = QPushButton("Foo")
        self.btn1.clicked.connect(btn1_callback)

        layout.addWidget(self.btn1)
        self.setLayout(layout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    app.exec_()

../ tests / test_ui.py

import sys
import unittest
import mock

from PySide.QtGui import *
from PySide.QtCore import *
from PySide.QtTest import QTest

import app.ui

application = QApplication(sys.argv)

class UiTest(unittest.TestCase):

    def setUp(self):
        self.ui = app.ui.Window()

    @mock.patch.object(app.ui, "btn1_callback")
    def test_btn1(self, callback):
        QTest.mouseClick(self.ui.btn1, Qt.LeftButton)
        self.assertTrue(callback.called)

if __name__ == '__main__':
    unittest.main()

运行python -m unittest discover tests将运行1测试,并且无法说未调用该函数。但是它将在控制台上显示“ 1”,所以我知道QTest确实设法使回调得以执行。

1 个答案:

答案 0 :(得分:1)

patch.object基本上修改了对名称app.ui.btn1_callback解析的访问权限。但是,直到 app.ui.Window()之后,您才可以调用它。该参考不受修补程序的影响。您必须实例化UI并在补丁仍然有效时运行测试:

class UiTest(unittest.TestCase):
    def setUp(self):
        p = mock.patch.object(app.ui, "btn1_callback")
        self.addCleanup(p.stop)
        self.callback = p.start()
        self.ui = app.ui.Window()

    def test_btn1(self):
        QTest.mouseClick(self.ui.btn1, Qt.LeftButton)
        self.assert(self.callback.called)

现在startup负责启用补丁,并安排最终的禁用时间。 Window(),并且测试本身在已经修补了回调的环境中运行。

(使用addCleanup比定义tearDown来调用p.stop()更为安全,因为它可以确保即使由于任何原因未调用tearDown也会停止补丁。)< / p>