gpt4 book ai didi

Python单元测试.mock : patched class method called but assertion fails

转载 作者:行者123 更新时间:2023-12-01 00:53:57 25 4
gpt4 key购买 nike

我正在尝试模拟实用程序类的几个组件。虽然 assert_used() 对于一种方法是可以的,但对于另一种方法则失败,但我确信这两种方法都会被调用。我在 Windows 10 上运行 Python 3.7.3。

我已经将我的场景精简到了最基本的部分。实用程序类(util.py):

class api:

@staticmethod
def send(data):
print("sending %s" % data)

class logger:

@staticmethod
def info(s):
print("INFO: %s" % s)

@staticmethod
def error(s):
print("ERROR: %s" % s)

工作正常的单元测试变体:

import unittest
from unittest.mock import patch
from util import api

def do_something():
api.logger.info("doing something")
api.send("some data")

@patch("util.api.logger")
class Test(unittest.TestCase):

def test_do_something(self, mock_logger):
do_something()
mock_logger.info.assert_called()

失败的:

import unittest
from unittest.mock import patch
from util import api

def do_something():
api.logger.info("doing something")
api.send("some data")

@patch("util.api")
class Test(unittest.TestCase):

def test_do_something(self, mock_api):
do_something()
mock_api.send.assert_called()

运行测试时,我得到两个 print() 输出:

INFO: doing something
sending some data

所以我确信这两种方法都被调用了。

很可能我犯了一些愚蠢的错误,因为我对 python 真的很陌生......

更多背景:

在我的精简场景中,do_something() 只是一组函数的替代,这些函数是我的测试对象,在我的真实场景中,这些函数实际上是在单独的 python 文件中定义的。在生产环境中,它在提供实用程序类 API 的框架上下文中运行。在我的测试环境中,util.py 本身就是生产 api 的模拟。要测试的 py 文件(而不是 def do_something(): ...)的加载方式如下:

path = os.getcwd() + "<local path to py file to be tested>"
globals().update({ **runpy.run_path(path, init_globals=globals()), **globals() })

因此,我无法修改测试场景中的 do_something() 代码。

最佳答案

这是一个棘手的问题。

问题在于 api 类在修补之前就已由测试类导入。来自 patch 的文档:

The target is imported when the decorated function is executed, not at decoration time.

由于您在测试类中首先导入 api 类,因此当您运行测试时,该人不会得到修补。 Python 认为它已经被导入了。

请注意,logger 类的情况并非如此,因为您从未导入它。如果你这样做了,第一个测试也会失败。

最简单的修复 - 将导入移至测试函数内。

def do_something():
from util import api
api.logger.info("doing something")
api.send("some data")

现在 patch 将执行导入 - 因此模拟被放置在测试范围而不是实际的类中。

关于Python单元测试.mock : patched class method called but assertion fails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56363365/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com