2

我是一位经验丰富的 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

所以基本的想法是只在“生成”函数的第 3 次调用中获得 10。

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

def my_generate_hash():
    return 99

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

Buuut 我无法实现属性“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()

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

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

4

2 回答 2

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与您在问题中尝试的方式相同的方式修补类:

使用 a @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
于 2013-10-16T20:41:19.943 回答
1

看起来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)
于 2013-10-17T10:17:06.777 回答