重新分配模块的功能以进行测试



我曾考虑从测试套件中的标准库模块中重新分配一些函数,但我发现这样做会产生全局影响(当我希望它们只在本地产生影响时)。例如:

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 (!)

我必须在test()结束时将time.sleep恢复到以前的状态吗?

这是不是让人感到气馁。。。我应该如何进行此类测试?

如果您有一个对象要以这种方式进行测试,则应该使用依赖注入和mocking。从程序的"顶部"传入一个对象(在本例中为时间)。然后,您可以通过传入模拟版本来对单个函数或对象进行单元测试。

示例:

# 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>

最新更新