2016-08-31 1 views
2

私は次のクラスとメソッドを持っている:datetimeを使用してメソッドをユニットテストするにはどうすればよいですか?

class DateTimeHelper(object): 

    @staticmethod 
    def get_utc_millisecond_timestamp(): 
     (dt, micro) = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f').split('.') 
     return "%s.%03d" % (dt, int(micro)/1000) # UTC time with millisecond 

どのように私はユニットそれをテストすることができますか?これは簡単ですが、私は完全に困惑しています。それは私の最初のユニットテストです。

+0

モックアウト 'utcnow'が知られている日時を返すように? – jonrsharpe

+0

datetimeを「模擬」することができます:http://stackoverflow.com/questions/4481954/python-trying-to-mock-datetime-date-today-bod-not-working。 – alecxe

答えて

5

unittest.mock library(Python 3.3以降、バックポートはmock)を使用して、コードの対象外のコードへの呼び出しを置き換えます。

with mock.patch('datetime.datetime') as dt_mock: 
    dt_mock.utcnow.return_value.strftime.return_value = '2016-08-04 12:22:44.123456' 
    result = DateTimeHelper.get_utc_millisecond_timestamp() 

あなたはstrftime()引数をテストすることは重要であると感じた場合は、dt_mock.utcnow.return_value明示的datetimeオブジェクトにを与える:ここで

、私は文字列オブジェクトを返すために、あまりないだけutcnow()なく、strftime()をモックと思います代わりに戻る。 、あなたのユニットテストでは、

testdt = datetime.datetime(2016, 8, 4, 12, 22, 44, 123456) 
with mock.patch('datetime.datetime') as dt_mock: 
    dt_mock.utcnow.return_value = testdt 
    result = DateTimeHelper.get_utc_millisecond_timestamp() 

かへの参照を保持するためにfrom datetime import datetimeを使用する:あなたはちょうどdatetime.datetime.utcnowクラスメソッドをモックすることができないとして、あなたが、しかしモック前に、そのテスト・オブジェクトを作成する必要があると思います嘲笑されないクラス。

デモ:

>>> from unittest import mock 
>>> import datetime 
>>> class DateTimeHelper(object): 
...  @staticmethod 
...  def get_utc_millisecond_timestamp(): 
...   (dt, micro) = datetime.datetime.utcnow().strftime('%Y-%m-%d %H:%M:%S.%f').split('.') 
...   return "%s.%03d" % (dt, int(micro)/1000) # UTC time with millisecond 
... 
>>> with mock.patch('datetime.datetime') as dt_mock: 
...  dt_mock.utcnow.return_value.strftime.return_value = '2016-08-04 12:22:44.123456' 
...  result = DateTimeHelper.get_utc_millisecond_timestamp() 
... 
>>> result 
'2016-08-04 12:22:44.123' 
>>> testdt = datetime.datetime(2016, 8, 4, 12, 22, 44, 123456) 
>>> with mock.patch('datetime.datetime') as dt_mock: 
...  dt_mock.utcnow.return_value = testdt 
...  result = DateTimeHelper.get_utc_millisecond_timestamp() 
... 
>>> result 
'2016-08-04 12:22:44.123' 
+0

フリーズグン(https://github.com/spulec/freezegun)サードパーティ製のモジュールは、非常に便利で時間の節約につながることもあります。(便利なデコレータとコンテキストマネージャを持っています) –

+0

'freezegun'は精巧なものを生成しますモック;私はこれまで、あなたが 'モック 'で同じことを達成できなかったユースケースを見ていませんでした。 'モック'がデファクトスタンダードであるため、私は 'フリーズンン 'を選択するのかどうか分からない。 –

+0

私は 'urllib'を使って、'要求 'でできなかったものをどこでも再現できないところを見たことがありません...それはほとんど利便性です。 –

関連する問題