如何正确使用patch.object()

How to use patch.object() correctly

我试图了解 Mock 和 patch(),但我被困在一个有点简单的例子上。假设我在 main.py 中有以下函数,它测试是否是工作日。

from datetime import datetime

def is_weekday():
    today = datetime.today()
    return (0 <= today.weekday() < 5)

我想 运行 我的测试有两种可能的结果:False 如果我模拟周六或周日,或者 True 如果是工作日。现在,我在调用 main.is_weekday 时显然没有嘲笑任何东西,所以我的测试目前失败了,因为它是周末。我该如何解决?

from unittest.mock import Mock, patch
import pytest
import main

def test_weekday():
    datetime = Mock()
    tuesday = datetime(year=2019, month=1, day=1)
    datetime.today.return_value = tuesday
    with patch.object(datetime, "main.is_weekday", tuesday) as mock_method:
        expected = True
        actual = main.is_weekday() # how do I mock datetime.today()?
        assert actual == expected

主要问题是您没有在 main 模块中修补 datetimepatch.object 的第一个参数是你想要修补的东西,因为你传递的是你的 datetime Mock 对象,这对你没有任何好处。

我会像这样重组你的测试:

from unittest.mock import Mock, patch
from datetime import datetime
from mockito import when, ANY

import main


def test_weekday():
    testdate = datetime(year=2019, month=1, day=1)
    with patch("main.datetime", wraps=datetime) as mock_datetime:
        mock_datetime.today.return_value = testdate
        assert main.is_weekday()


def test_weekend():
    testdate = datetime(year=2019, month=1, day=5)
    with patch("main.datetime", wraps=datetime) as mock_datetime:
        mock_datetime.today.return_value = testdate
        assert not main.is_weekday()

在这里,我们将 main.datetime 替换为模拟对象,然后对其进行配置,以便在 main 模块中调用 datetime.today() 将 return 特定日期.

然后我们测试代码在工作日和 周末。