5

私はモックにさまざまなツールを使用して、最適なものを見つけようとしています。私はその単純さからflexmockが本当に好きですが、datetime.datetime.now()の動作をモックする方法を理解できません。

フレックスモックで次の動作をモックする方法は?

>>> from datetime import datetime
>>> mocker = Mocker()
>>> fake_datetime=mocker.replace(datetime)
>>> fake_datetime.now()
<mocker.Mock object at 0x027F1990>
>>> mocker.result(datetime(year=2012, month=12, day=12))
>>> mocker.replay()
>>> datetime.now()
datetime.datetime(2012, 12, 12, 0, 0)

flexmock で同じことを試すと:

>>> from datetime import datetime  
>>> fake_datetime = flexmock(datetime)
Traceback (most recent call last):
  File "C:\virtualenvs\webui\lib\site-packages\flexmock.py", line 1194, in flexmock
    return _create_partial_mock(spec, **kwargs)
  File "C:\virtualenvs\webui\lib\site-packages\flexmock.py", line 1013, in 
_create_partial_mock
if (_attach_flexmock_methods(mock, Mock, obj_or_class) and
  File "C:\virtualenvs\webui\lib\site-packages\flexmock.py", line 1030, in
_attach_flexmock_methods
'Python does not allow you to mock builtin objects or modules. '
    'Python does not allow you to mock builtin objects or modules. '
MockBuiltinError: Python does not allow you to mock builtin objects or modules.
Consider wrapping it in a class you can mock instead

また

>>>flexmock(datetime).should_receive('datetime.now').and_return(datetime.datetime(2012,12,10))
>>> datetime.datetime.now()
Traceback (most recent call last):
  File "<console>", line 1, in <module>
AttributeError: 'function' object has no attribute 'now'
4

1 に答える 1

4

最初のアプローチは正しい考えでしたが、残念ながらPythonではdatetime.datetimeなどの組み込みオブジェクトを変更できません。flexmockmonkey-オブジェクトにパッチを適用し、実行時にメソッド呼び出しをハイジャックしますが、この場合は不可能です。例外のエラーは実際には解決策を示しています。datetime.datetimeを独自のクラスでラップして、それをモックすることができます。しかし、Mockerが例で行ったことを本当に実行し、必要なものを返すnow()メソッドを使用して偽のオブジェクトを作成したい場合は、非常に簡単に実行できます。

fake_datetime = flexmock(now=lambda: datetime(year=2012, month=12, day=12))

ただし、もちろん、datetime.now()への通常の呼び出しは、呼び出し元のコードに偽のdatetimeオブジェクトを挿入しない限り、flexmockによってハイジャックされることはありません。

flexmockのdatetime.should_receive('datetime.now')は連鎖メソッド呼び出しを対象としているため、2番目のアプローチではエラーが発生しました。つまり、datetime.datetime.now()ではなくdatetime.datetime()。now()のような呼び出しを予期しているため、メソッドnow()を持たない関数であると予期しているdatetimeについて不平を言うことになります。

于 2013-03-01T13:45:23.507 に答える