2016-06-20 35 views
2

無限ループ用のunittestを作成するために、このコードに固執しています。無限ループのunittests

try: 
    while True: 
    time.sleep(60) 
except: 
    fun() 

無限ループの単位テストを作成するにはどうすればよいですか?

+2

(https://docs.python.org /3/library/unittest.mock.html#unittest.mock.Mock.side_effect)。 – jonrsharpe

+0

しかし、While Trueが使用されていると無限ループになります。どうすれば同じことを解決できますか? – sam

+3

実際に*文書を読んでください*副作用は*あなたが選択したときにループを終了できるようにする "例外(クラスまたはインスタンス)" *にすることができます。 – jonrsharpe

答えて

3

あなたはどのような行動をテストしていますか?ここには副作用や戻り値はありません。実際には何もテストする必要はありません。ループの後にfunが呼び出された場合、それはオーバースペックのように聞こえます。ループの終了後に不変量が維持されている場合は、sleepにパッチを適用して例外をスローし、関数が実行された後の状態を調べることができます。

from unittest import TestCase, main 
from unittest.mock import patch 

import module_under_test 

class TestLoop(TestCase): 
    # patch sleep to allow loop to exit 
    @patch("time.sleep", side_effect=InterruptedError) 
    def test_state_reset(self, mocked_sleep): 
     # given 
     obj = module_under_test.SomeClass() 

     # when 
     obj.infinite_loop() 

     # then assert that state is maintained 
     self.assertFalse(obj.running) 

if __name__ == "__main__": 
    main() 

あなたは `[` side_effect`s]様々なを持っている `time.sleep`をunittest.mock`できmodule_under_test.py

import time 

class SomeClass: 
    def __init__(self): 
     self.running = False 

    def fun(self): 
     self.running = False 

    def infinite_loop(self): 
     self.running = True 
     try: 
      while True: 
       time.sleep(60) 
     except: 
      self.fun() 
3

while True: ...の代わりにitertools.count機能を使用して、無限ループをコードすることができます。これは、コードが多少効率が悪くなるかもしれないが、それは無限ループをmockすることが可能になる:

import itertools 

try: 
    for _ in itertools.count(): 
     time.sleep(60) 
except: 
    fun() 

次に、あなたのテストで行います

from unittest.mock import patch 

with patch("itertools.count") as mock_count: 
    # tests go here