【问题标题】:Python patch existing classPython补丁现有类
【发布时间】:2013-10-16 20:03:48
【问题描述】:

我是一名经验丰富的 PHP/Ruby 开发人员,但现在我正在与 Python 作斗争,我真的需要你的帮助。

我需要通过添加静态属性和覆盖静态函数来修补现有类。

让我给你举个例子:

class Test():
    @staticmethod
    def generate():
        return 10

但在我的测试套件中,我需要获得以下课程:

class Test():
    count = 1
    @staticmethod
    def generate():
        if Test.count < 3:
            Test.count += 1
            return 1
        else:
            return 10

所以基本思想是仅在第三次调用“生成”函数时获得 10。

我的第一种方法是使用“补丁”技术,所以我这样做了:

def my_generate_hash():
    return 99

with patch.object(Test, 'generate', staticmethod(my_generate_hash)):
    print "Got %d" % check_hash()

但我无法实现属性“count”并在覆盖方法中使用它(

第二个想法是“模拟”一些东西!所以..

mock = MagicMock(Test)
mock.count = 1
def my_generate_hash():
    if Test2.count < 3:
        Test2.count += 1
        return 1
    else:
        return 10
mock.generate = my_generate_hash
with patch('__main__.Test', mock):
    print Test.generate()

但在实际情况下,我在“测试”类中有其他方法,所以它不起作用。

我被困住了。任何帮助将不胜感激!

【问题讨论】:

    标签: python testing mocking patch


    【解决方案1】:

    将原始Test 类子类化以用于您的测试可能更简单:

    class Test(object):
        @staticmethod
        def generate():
            return 10
    
    class PatchedTest(Test):
        count = 1
        @staticmethod
        def generate():
            if Test.count < 3:
                Test.count += 1
                return 1
            else:
                return 10
    

    替换功能也可以通过两种更好的方式来完成,这两种方式都应该使修补Test 类变得更加容易,就像您在问题中尝试的方式一样:

    使用@classmethod,允许函数访问分配给它的类:

    class PatchedTest(Test):
        count = 1
    
        @classmethod
        def generate(cls):
            if cls.count < 3:
                cls.count += 1
                return 1
            else:
                return 10
    

    改用生成器 - 每次调用该函数时,它都会从上次停止的地方继续执行。但是,这仅在您迭代函数结果时才有效:

     def alternative_generate():
         yield 1
         yield 1
         yield 10
    

    【讨论】:

      【解决方案2】:

      看起来 in 可以有不同的方式。

      self.count = 0
      
      def generate():
      if self.count < 3 
           self.count += 1
           return 10
      else:         
          return 99
      
      with patch.object(Test, 'generate', generate):
          self.assertEqual(Test.generate(), 10)
          self.assertEqual(Test.generate(), 10)
          self.assertEqual(Test.generate(), 10)
          self.assertEqual(Test.generate(), 99)
          self.assertEqual(Test.generate(), 99)
      

      【讨论】:

        猜你喜欢
        • 2011-04-15
        • 2017-10-05
        • 1970-01-01
        • 2022-12-09
        • 1970-01-01
        • 2012-12-18
        • 1970-01-01
        • 2017-01-31
        • 2012-12-12
        相关资源
        最近更新 更多