gpt4 book ai didi

python-3.x - 协程的 Python 3.8 模拟

转载 作者:行者123 更新时间:2023-12-04 13:57:35 25 4
gpt4 key购买 nike

我尝试编写单元测试来检查类方法是否被断言。

class Application:
async def func1(self):
await self.func2(self.func3())

async def func2(self, val):
pass

async def func3(self):
pass

并对其进行单元测试:
@pytest.mark.asyncio
async def test_method():
app = Application()

with patch.object(Application, 'func2') as mock:
await app.func1()
mock.assert_awaited_with(app.func3())

但我得到错误:
AssertionError: expected await not found.
Expected: func2(<coroutine object Application.func3 at 0x7f1ecf8557c0>)
Actual: func2(<coroutine object Application.func3 at 0x7f1ecf855540>)

为什么?我调用了相同的方法。我能用它做什么?

最佳答案

有一个asynctest这使得模拟(修补)异步函数变得更容易。

Patching

Patching is a mechanism allowing to temporarily replace a symbol (class, object, function, attribute, …) by a mock, in-place. It is especially useful when one need a mock, but can’t pass it as a parameter of the function to be tested.

For instance, if cache_users() didn’t accept the client argument, but instead created a new client, it would not be possible to replace it by a mock like in all the previous examples.

When an object is hard to mock, it sometimes shows a limitation in the design: a coupling that is too tight, the use of a global variable (or a singleton), etc. However, it’s not always possible or desirable to change the code to accomodate the tests. A common situation where tight coupling is almost invisible is when performing logging or monitoring. In this case, patching will help.

A patch() can be used as a context manager. It will replace the target (logging.debug()) with a mock during the lifetime of the with block.


async def test_with_context_manager(self):
client = asynctest.Mock(AsyncClient())
cache = {}

with asynctest.patch("logging.debug") as debug_mock:
await cache_users_async(client, cache)

debug_mock.assert_called()

请注意,函数的路径以字符串形式提供给 asynctest.patch而不是作为一个对象。

另外,在 func1 func2在获取 func3作为协程,不等待它运行(无等待)。

你可以尝试这样的事情:
import asynctest
@pytest.mark.asyncio
async def test_method():
app = Application()

with asynctest.patch('Application.func2') as mock:
await app.func1()
mock.assert_awaited_with(app.func3())

关于python-3.x - 协程的 Python 3.8 模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58792199/

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