Python 断言'mocked_function.called',用于unittest

Python 断言'mocked_function.called',用于unittest,python,qt,unit-testing,mocking,pyside,Python,Qt,Unit Testing,Mocking,Pyside,我希望为PySide UI实现单元测试,但不知道如何正确地断言连接到UI元素的函数已被调用 到目前为止,我已经尝试了不同的方法来导入我正在编写测试的模块。模拟函数的不同方式 ../app/ui.py 导入系统 从PySide.QtGui导入* 从PySide.QtCore导入* def btn1_回调: 打印1 类WindowQWidget: 定义初始自我,*args,**kwargs: 超视窗,self.\uuuuu init\uuu*args,**kwargs 布局=QVBoxLayout

我希望为PySide UI实现单元测试,但不知道如何正确地断言连接到UI元素的函数已被调用

到目前为止,我已经尝试了不同的方法来导入我正在编写测试的模块。模拟函数的不同方式

../app/ui.py

导入系统 从PySide.QtGui导入* 从PySide.QtCore导入* def btn1_回调: 打印1 类WindowQWidget: 定义初始自我,*args,**kwargs: 超视窗,self.\uuuuu init\uuu*args,**kwargs 布局=QVBoxLayout self.btn1=qpushbuttonfo self.btn1.clicked.connectbtn1\u回调 layout.addWidgetself.btn1 self.setLayoutlayout 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': app=QApplicationsys.argv 窗口 橱窗秀 app.exec_ ../tests/test_ui.py

导入系统 导入单元测试 导入模拟 从PySide.QtGui导入* 从PySide.QtCore导入* 从PySide.QTest导入QTest 导入app.ui application=QApplicationsys.argv UiTestunittest.TestCase类: def设置自我: self.ui=app.ui.Window @mock.patch.objectapp.ui,btn1\u回调 def测试_btn1self,回调: QTest.mouseClickself.ui.btn1,Qt.LeftButton self.assertTruecallback.called 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': unittest.main 运行python-m unittest discover测试将运行1测试并失败,表示未调用该函数。但是,它会将1打印到控制台,因此我知道QTest确实成功地导致了回调的执行。

patch.object基本上修改了对app.ui.btn1\u回调名称的访问解析。但是,在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负责启用修补程序,并安排其最终禁用。窗口和测试本身在回调已被修补的环境中运行

使用addCleanup比定义tearDown调用p.stop更安全,因为它确保即使没有出于任何原因调用tearDown,也会停止修补程序