Python 为测试目的重命名内置函数
我曾考虑在我的测试套件中重命名一些内置函数,但我发现这样做会产生全局影响(当我期望它们只在本地产生影响时)。例如:Python 为测试目的重命名内置函数,python,unit-testing,testing,Python,Unit Testing,Testing,我曾考虑在我的测试套件中重命名一些内置函数,但我发现这样做会产生全局影响(当我期望它们只在本地产生影响时)。例如: import time def test(): time.sleep = "hello" #woah there! time is mutable so this won't just apply locally! print time.sleep #prints <built-in function sleep> test() print time.slee
import time
def test():
time.sleep = "hello" #woah there! time is mutable so this won't just apply locally!
print time.sleep #prints <built-in function sleep>
test()
print time.sleep #prints hello (!)
导入时间
def test():
time.sleep=“你好”#哇!时间是可变的,所以这不仅仅适用于本地!
打印时间。睡眠#打印
测试()
打印时间。睡眠打印你好(!)
必须将时间还原到测试()结束时的睡眠状态吗
这是一件令人沮丧的事吗。。。我应该如何进行这种测试?如果您有一个对象要以这种方式进行测试,您应该使用和。从程序的“顶部”传入一个对象(在本例中为时间)。然后,您可以通过传入模拟版本来对单个函数或对象进行单元测试
例如:
# Function to be tested
def callSleep(timer):
timer.sleep(5)
# Example usage
def main():
import time
timer = time
callSleep(timer)
# Example test
def testFunction():
class MockTimer:
numCalled = 0
withValue = 0
def sleep(self, val):
self.numCalled += 1
self.withValue = val
mockTimer = MockTimer()
callSleep(mockTimer)
print "Num called:", mockTimer.numCalled, "with value", mockTimer.withValue
我会遵循上面@Joe的建议,但下面是解决您问题的快速方法。
至于为什么会发生这种情况,对time.sleep的引用是在全局范围内的,因此替换它的效果并不局限于局部范围
import time
def test():
old_sleep = time.sleep # Save a reference to the builtin
time.sleep = "hello" #shouldn't this just set time.sleep locally?
print 'Inside test:', time.sleep
time.sleep = old_sleep # replace the reference
print time.sleep #prints <built-in function sleep>
test()
print time.sleep #prints <built-in function sleep>
导入时间
def test():
old_sleep=time.sleep#保存对内置项的引用
time.sleep=“hello”#这不应该设置time.sleep本地吗?
打印“内部测试:”,time.sleep
time.sleep=old_sleep#替换引用
打印时间。睡眠#打印
测试()
打印时间。睡眠#打印
为什么不保存对内置的引用,然后在测试结束时恢复到它?您的范围概念不适用于对象。如果您有一个对可变对象的引用,无论该引用存在于何处,它都可以使该对象发生变异。@JohnY非常正确,我没有考虑过时间是可变的,现在清楚了为什么会发生这种情况。:)因此,“消磨时间”就是解决办法的确“通过模仿对象来消磨时间”。我们需要注意的是,时间
在使用它或调用使用它的东西(或调用调用使用它的东西的东西…)的任何地方都会被传递!这叫什么?我不认为范围是个问题,而是因为时间是可变的你最初问过为什么它看起来超出了范围。是的,我想这是猴子补丁,因为您不修改原始源代码,而是在运行时(临时)替换一些库进行测试。我做了!(当我发布时,我没有想到时间是可变的,回想起来,键入time**.*sleep
应该给它。):)是的,我想知道你为什么认为你可以分配时间。sleep,但没想到它会改变!