2012-12-26 36 views
5

Tôi đang cố gắng sử dụng các công cụ khác nhau để chế giễu và tìm hiểu tốt nhất. Tôi thực sự thích flexmock cho sự đơn giản của nó, nhưng tôi không thể tìm ra cách để mô phỏng hành vi của datetime.datetime.now().Mocking với Flexmock datetime.datetime.now

Làm thế nào để chế giễu sau hành vi trong flexmock?

>>> 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) 

Khi tôi cố gắng cùng trong 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 

hoặc

>>>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' 

Trả lời

4

tiếp cận đầu tiên của bạn đã có ý tưởng đúng nhưng tiếc là Python không cho phép bạn sửa đổi đối tượng dựng sẵn như datetime.datetime . flexmock khỉ-vá các đối tượng và tấn công các cuộc gọi phương thức tại thời gian chạy mà không phải là có thể trong trường hợp này. Lỗi trong ngoại lệ thực sự đề cập đến một giải pháp - bạn có thể gói datetime.datetime trong lớp của riêng bạn và sau đó giả lập điều đó. Nhưng nếu bạn thực sự muốn làm gì nhạo báng đã làm trong ví dụ của bạn và chỉ cần tạo một đối tượng giả với một hiện phương pháp() trả về những gì bạn muốn, bạn có thể làm điều đó khá dễ dàng:

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

Nhưng, tất nhiên, các cuộc gọi thông thường tới datetime.now() sẽ không bị tấn công bởi flexmock trừ khi bạn đã tiêm đối tượng datetime giả vào mã gọi.

tiếp cận thứ hai của bạn tạo ra một lỗi vì datetime.should_receive ('datetime.now') trong flexmock là có nghĩa là cho các cuộc gọi phương pháp xích. Có nghĩa là nó hy vọng một cuộc gọi như datetime.datetime(). Now() chứ không phải là datetime.datetime.now() để nó kết thúc lên phàn nàn về datetime mà nó expectes là một chức năng không có phương pháp now().