2009-06-26 7 views
2

辞書を返す関数の単体テストを書く必要があります。この辞書の値の1つはdatetime.datetime.now()ですが、テストのたびに変更されます。Python単体テストで揮発性の値を持つディクショナリ?

私は自分のアサートでそのキーを完全に無視したいと思います。今、私は辞書の比較機能を持っていますが、私は本当にこのようassertEqualを使用したい:

def my_func(self): 
    return {'monkey_head_count': 3, 'monkey_creation': datetime.datetime.now()} 

... unit tests 

class MonkeyTester(unittest.TestCase): 
    def test_myfunc(self): 
     self.assertEqual(my_func(), {'monkey_head_count': 3}) # I want to ignore the timestamp! 

は、これを行うための任意のベストプラクティスやエレガントな解決策はありますか?私はassertAlmostEqual()を認識していますが、これは浮動小数点iircにのみ便利です。

答えて

9

だけで比較を行う前に、辞書からタイムスタンプを削除します。

class MonkeyTester(unittest.TestCase): 
    def test_myfunc(self): 
     without_timestamp = my_func() 
     del without_timestamp["monkey_creation"] 
     self.assertEqual(without_timestamp, {'monkey_head_count': 3}) 

あなた自身がdatetime.now()を伴う時間関連のテストをたくさんやって見つけた場合、あなたはあなたのユニットテストのためのDateTimeクラスをモンキーパッチすることができます。あなたのユニットテストでdatetime.datetime.now()を呼び出すたび今、この

import datetime 
constant_now = datetime.datetime(2009,8,7,6,5,4) 
old_datetime_class = datetime.datetime 
class new_datetime(datetime.datetime): 
    @staticmethod 
    def now(): 
     return constant_now 

datetime.datetime = new_datetime 

を考えてみましょう、それは常にconstant_nowタイムスタンプを返します。あなたが/欲しい元datetime.datetime.now()に切り替える必要がある場合、その後、あなたは

datetime.datetime = old_datetime_class 

と物事が正常に戻っなります簡単な言うことができます。あなたが与えた簡単な例では、私は比較する前にdictからタイムスタンプを削除することをお勧めしますが、この種のものは役に立ちます。

+1

なぜ私はその単純な解決策を考えなかったのですか?私はmy_funcの可能な戻り値の多くをテストする予定ですが、あなたが提案したようにdatetimeをmonkeypatchします。多くのappriciated、本当に賢い! – pojo

+2

teardownメソッドでdatetimeを元に戻すコードを置く必要があります。つまり、このユニットテストは他のテストクラスに影響しません。 –

+3

別のオプションは、datetime.datetime.nowを名前付きパラメータのデフォルトとして渡します。単体テストであなた自身の関数を渡してください。これにより、Monkeypatchingが回避されます。 –

関連する問題