繁体   English   中英

Python 单元测试补丁未按预期工作

[英]Python unittest patching is not working as expected

我有以下项目结构:

root/
|-mylib/
  |-tests/
  | |-__init__.py
  | |-test_trend.py
  |-__init__.py
  |-data.py
  |-trend.py

trend.py

from mylib.data import get_item

def get_trend(input: str):
    item = get_item(input)
    return f"Trend is: {item}"

内部data.py

def get_item(id):
    print("ORIGINAL")
    return get_item_from_db(id)

测试

我想单独测试get_trend ,因此我在内部修补get_itemtest_trend.py

import unittest
from unittest.mock import patch
from mylib.trend import get_trend

def p__get_item(input):
    return 0

class MyTestCase(unittest.TestCase):
    @patch("mylib.data.get_item", new=p__get_item)
    def test_trend(self):
        v = get_trend()
        self.assertEqual(v, "Trend is: 0")

但是当我运行测试时(命令是从root目录中运行的):

python -m unittest discover

我看到日志显示原来的get_item被调用了。 测试当然失败了。

我究竟做错了什么?


尝试 1

如果我尝试这种其他风格的 APIL patch

class MyTestCase(unittest.TestCase):
    @patch("mylib.data.get_item")
    def test_trend(self, mocked_fun):
        mocked_fun.return_value = 0
        v = get_trend()
        self.assertEqual(v, "Trend is: 0")

它仍然不起作用。 在控制台日志中,我可以看到正在打印ORIGINAL并且测试失败。

实验一

如果我将@patch中的target更改为不存在的属性,例如:

@patch("mylib.data.non_existing", new=p__get_item)

我实际上从库中收到一条错误消息,指出该模块不包含此类属性。 因此,似乎mylib.data.get_item已被正确定位,但仍未进行修补。

解释

get_itemmylib.trend模块中调用,但是,您在mylib.data模块中对其进行了修补,这是错误的地方。 patch通过替换import上的对象来工作。 在这种情况下,您想要修补get_item模块中的mylib.trend而不是mylib.data

解决方案

class MyTestCase(unittest.TestCase):
    @patch("mylib.trend.get_item")
    def test_trend(self, mocked_get_item):
        mocked_get_item.return_value = 0
        ...

笔记

可以在官方 python 文档中找到有关在哪里打补丁的更多说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM