我是一名经验丰富的 PHP/Ruby 开发人员,但现在我正在与 Python 作斗争,我真的需要你的帮助。
我需要通过添加静态属性并覆盖静态函数来修补现有类以使用它。
让我向您展示示例:
class Test():
@staticmethod
def generate():
return 10
但在我的测试套件中,我需要获得以下类(class):
class Test():
count = 1
@staticmethod
def generate():
if Test.count < 3:
Test.count += 1
return 1
else:
return 10
所以基本思想是仅在第三次调用“generate”函数时获取 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()
但在实际情况下,我在“Test”类中有其他方法,所以它不起作用。
我被困住了。任何帮助将不胜感激!
最佳答案
对原始 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
关于Python 修补现有类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19412714/