【问题标题】:problems with staticmethod decorators静态方法装饰器的问题
【发布时间】:2013-07-30 14:30:18
【问题描述】:

我一直在我的一些函数上使用@staticmethod 装饰器,以便为它们编写测试用例。我只是想测试类中的几个方法,而不必初始化整个类,所以我认为这将是一个完美的方法。

但是,现在测试代码运行良好,但实际代码给了我一个错误。大多数函数都有self 参数传递给它们,所以@staticmethod 装饰器会导致它们失败。

有没有不使用@staticmethod 来测试方法的方法?如果没有,在不更改大部分生产代码的情况下解决此问题的最佳方法是什么?

Class DBMethod():
      @staticmethod
      def getVN(self, tN):
          curs = self.connection.cursor()
          curs.execute ('SELECT * FROM ' + tN)
          vL = list(map(lambda x: x[0], curs.description))[0]
          return vL

和测试类

Class DBTestClass(unittest.TestCase):
      def test_getVN(self):
            self.assertEqual(DBMethod.getVN(self, 'tbN'), 'VER')

【问题讨论】:

  • staticmethods只是类似的函数;它们确实采用self 参数,因为它们独立于任何实例。你希望self 在这里做什么?
  • 没有选项只初始化'部分';静态方法也不是到达那里的方法。要么全有,要么全无;静态方法是“无”;常规方法需要“全部”。
  • 是的,我明白了。当我开始编写测试代码时,我没有意识到这一点。显然大多数生产代码都依赖于self 参数。
  • self 参数指的是实例,例如保存数据库连接。
  • 我无法真正初始化类 (stackoverflow.com/questions/17836939/…)。我一直在使用内存数据库。 @staticmethod 似乎是一种无需重载或模拟 init 方法的方法。现在我被困住了。

标签: python unit-testing mocking static-methods


【解决方案1】:

我建议您使用 Python 的可用测试框架之一,例如:

这些框架使编写测试类中每个方法的测试变得容易,并根据需要提供适当的测试脚手架和测试数据。恕我直言,比尝试手工测试要容易得多。

【讨论】:

    【解决方案2】:

    下面的mock补丁可以跳过init部分(其实我不知道你为什么在这里避免“mock the init method”,所以把我的猜测贴在这里):

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    import os
    import unittest
    from mock import patch
    
    
    class DBThing(object):
        moo = "bar"
    
        def __init__(self):
            self.moo = "hi"
    
        def foo(self):
            return self.moo
    
    class Test_init(unittest.TestCase):
        """Test DBThing init"""
        def setUp(self):
            pass
    
        def tearDown(self):
            pass
    
        def testInit(self):
            dbt = DBThing()
            self.assertEqual(dbt.foo(), "hi")
    
        def testNoInit(self):
            with patch('__main__.DBThing.__init__', return_value=None):
                dbt = DBThing()
                self.assertEqual(dbt.foo(), "bar")
    
    if __name__ == '__main__':
        import nose
        nose.run(defaultTest=__name__)
    

    【讨论】:

    • 非常感谢。很抱歉,我无法验证您的方法。我最终使用了另一种解决方法,可以让我完全避免 @staticmethod
    猜你喜欢
    • 1970-01-01
    • 2011-09-18
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2020-06-03
    • 2016-05-19
    • 2017-06-19
    • 2013-02-20
    相关资源
    最近更新 更多