如何在模块中模拟一个方法而不是模拟整个模块

How to mock up one method in a module other than mock up the whole module

我的目的是模拟 utcnow 的 return 值。我正在使用 pytest 并且非常新。

my_file.py模块my_module下的方法:

import datetime

def get_date_info() -> Tuple[int, str]:
    now_epoch = int(datetime.utcnow().strftime("%s"))
    # do something with now_epoch
    calculated_epoch = ...

    # another variable relies on datetime
    another_variable = datetime.fromtimestamp(calculated_epoch).strftime("%H")
return (now_epoch, another_variable)

我的 pytest 方法测试:

from my_module.my_file import get_date_info
import datetime
import mock

@mock.patch("my_module.my_file.datetime")
def test_get_date_info():
        mock_dt.utcnow = mock.Mock(return_value=datetime.datetime(2002, 1, 1))
        actual_epoch, actual_another_variable = get_date_info()
        # assert code here 

returned actual_epoch 与模拟日期是准确的,不幸的是下面的代码没有 return str 但 <MagicMock name='datetime.fromtimestamp().strftime()' id='140249763149088'>

datetime.fromtimestamp(calculated_epoch).strftime("%H")

有谁知道导致此问题的原因以及我该如何解决?

问题是您仅在模拟 utcnow,因此当在实际代码中调用 utcnow 时 - 它 return 是您的模拟值。您还必须模拟 datetime.fromtimestamp 才能将其 return 您的模拟值。 例如:

mock_dt.fromtimestamp = mock.Mock(return_value=datetime.datetime(2002, 1, 1))