3

テスト スイートでいくつかの組み込み関数の名前を変更することを検討していましたが、そうするとグローバルな効果があることがわかりました (ローカルでのみ効果があると予想していたのに)。例えば:

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

time.sleepの終わりに以前の状態に戻さなければなりませんtest()か?

これは落胆することですか...この種のテストをどのように行うべきですか?

4

2 に答える 2

3

この方法でテストしたいオブジェクトがある場合は、依存性注入モックを使用する必要があります。プログラムの「トップ」からオブジェクト (この場合は時間) を渡します。次に、モックアウトされたバージョンを渡すことで、個々の関数またはオブジェクトを単体テストできます。

例:

# 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
于 2012-08-29T11:34:44.827 に答える
1

上記の@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>
于 2012-08-29T11:41:37.697 に答える