为单元测试断言 `mocked_function.called`
Asserting `mocked_function.called` for unittest
我正在为 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 确实设法导致执行回调。
patch.object
基本上修改了对名称 app.ui.btn1_callback
解析的访问权限。但是,在 after 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
因任何原因未被调用也能停止补丁。 )
我正在为 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 确实设法导致执行回调。
patch.object
基本上修改了对名称 app.ui.btn1_callback
解析的访问权限。但是,在 after 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
因任何原因未被调用也能停止补丁。 )