【问题标题】:Mock a PyQt Method模拟 PyQt 方法
【发布时间】:2019-08-27 14:39:14
【问题描述】:

我有一个继承自 PyQT5 类 QWidget 和 Ui_Dialog 的现有类。

我想使用与 GUI 完全无关的类的一些功能。因此,我试图模拟出相关位,例如 __init__ 函数,它有很多特定于 GUI 的代码。类中还有一个特定的方法需要覆盖 (_getSqlQuery)。

class TestPyQgs(unittest.TestCase):
  def test_comment_parsing(self):
    query = "SELECT * FROM test"
    with patch.object(DlgSqlWindow, "__init__", lambda x, y, z: None):
      with patch.object(DlgSqlWindow, "_getSqlQuery", return_value=query):
        a = DlgSqlWindow(None,None)
        self.assertEqual(a.parseSQL(), query)

不幸的是,这不起作用,因为从 QtWidget 继承的任何东西(如 DlgSqlWindow 所做的那样)都必须在基类上调用 init,所以我得到super-class __init__() of type DlgSqlWindow was never called。没有理智的方法可以做到这一点吗?否则我应该尝试重构代码以将 GUI 从功能中分离出来,或者也对 GUI 进行单元测试,我宁愿不这样做,因为我希望单元测试尽可能紧凑。

【问题讨论】:

    标签: python unit-testing mocking pyqt5


    【解决方案1】:

    一种可能的解决方案是只调用没有太多逻辑的超级QWidget:

    import unittest
    from unittest.mock import patch
    
    from PyQt5 import QtWidgets
    
    
    class Ui_Dialog(object):
        def setupUi(self, dialog):
            pass
    
    
    class DlgSqlWindow(QtWidgets.QWidget, Ui_Dialog):
        def _getSqlQuery(self):
            pass
    
        def parseSQL(self):
            return "SELECT * FROM test"
    
    
    def init(self, *args):
        QtWidgets.QWidget.__init__(self)
        # self.setupUi(self)
    
    
    class TestPyQgs(unittest.TestCase):
        def test_comment_parsing(self):
            app = QtWidgets.QApplication([])
            query = "SELECT * FROM test"
            with patch.object(DlgSqlWindow, "__init__", init):
                with patch.object(DlgSqlWindow, "_getSqlQuery", return_value=query):
                    a = DlgSqlWindow(None, None)
                    self.assertEqual(a.parseSQL(), query)
    
    
    if __name__ == "__main__":
        unittest.main()
    

    但正如您所指出的,最佳解决方案是重构您的代码,因为您似乎将业务逻辑与 GUI 混合在一起,正如您所见,这会导致一些不便并且不可维护。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-18
      • 2017-09-08
      • 1970-01-01
      相关资源
      最近更新 更多