2016-10-02 20 views
2

私はdatetimeをとり、このdatetimeがどの期間に属しているかを返すメソッドを持っています。たとえば、 "yesterday"や "a month ago"などです。時間依存メソッドをテストする

from datetime import datetime 


def tell_time_ago(basetime): 
    difference = datetime.now() - basetime 

    days = difference.days 
    seconds = difference.seconds 
    hours = seconds/3600 
    minutes = seconds/60 

    if days and days == 1: 
     return 'Yesterday' 
    elif days and days != 1 and days < 7: 
     return '%s days ago' % days 
    elif days and days != 1 and 7 < days < 31: 
     return 'Within this month' 
    elif days and days != 1 and 30 < days < 365: 
     return '%s months ago' % (days/30) 
    elif days and days != 1 and 365 <= days < 730: 
     return 'A year ago' 
    elif days and days != 1 and days >= 730: 
     return '%s years ago' % (days/365) 

    elif hours and hours == 1: 
     return 'An hour ago' 
    elif hours and hours != 1: 
     return '%s hours ago' % hours 

    elif minutes and minutes == 1: 
     return 'A minute ago' 
    elif minutes and minutes != 1: 
     return '%s minutes ago' % minutes 

    elif seconds and seconds == 1: 
     return 'A second ago' 
    elif seconds and seconds != 1: 
     return '%s seconds ago' % seconds 

    else: 
     return '0 second ago' 

私はこのメソッドを拡張して、テストを書くつもりです。このメソッドのテストを書きたい場合は、システムの現在の日付を特定の日付に変更し、毎回通常の状態に戻す必要がありますので、日付が変更されただけでテストが失敗しませんか?例:

class TestCase(unittest.TestCase): 
    def test_timedelta(self): 
     a_year_ago = datetime(2015, 5, 12, 23, 15, 15, 53000) 
     assert tell_time_ago(a_year_ago) == 'A year ago' 

このテストを2年後に実行すると失敗します。最善のアプローチは何ですか?

+1

値を静的にしないでください。ちょうど 'datetime'を使用して1年後に日付を生成してください。 –

+0

私はそれのような何かをすることができるか分からなかった!ありがとう – Juggernaut

+1

あなたはまた、次のいずれかを行うことができます:時間を模擬するために['freezegun'](https://github.com/spulec/freezegun)を使います。または['humanize'](https://github.com/jmoiron/humanize)にする必要はありません。 – jonrsharpe

答えて

1

一般的には、自明でない関数やクラスを可能な限り数学関数(例えば、sin(x))に近づけることをお勧めします。同じ入力が与えられていると、数学関数は、現在の日付、ランダムな選択肢などに関係なく、毎回同じ出力を返します。

  • あなたの関数が現在の日付または時刻に依存する重要なロジックを実行しない場合は、現在の日付または時刻を外部に渡します。

  • 関数がランダムな選択を行う場合は、擬似乱数ジェネレータに渡します。

ので、たとえば、代わりのために:

import datetime 

def foo(): 
    ... 
    now = datetime.datetime.now() 
    ... 

foo() 

使用

import datetime 

def foo(now): 
    ... 
    ... 

foo(datetime.datetime.now()) 

これは、複数の実行間であなたの自明でないコードが一貫します。

  1. 予想通りにテストできます。

  2. 生産に失敗した場合は、問題を再構築する方が簡単です。

関連する問題