首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Python中模拟异步属性

在Python中模拟异步属性
EN

Stack Overflow用户
提问于 2022-09-25 11:44:49
回答 1查看 65关注 0票数 1

下面的示例类具有一个属性bar,与async_main()中的属性一样,因为它(理论上)在返回所有内容的答案之前做了一些IO工作。

代码语言:javascript
复制
class Foo:

    @property
    async def bar(self):
        return 42


async def async_main():
    f = Foo()
    print(await f.bar)

我在测试它时遇到了困难,因为Mock、MagicMock和AsyncMock的常见嫌疑并不能像预期的那样处理属性。我目前的解决办法是:

f.bar = some_awaitable()

因为这使得f.bar成为一个可以等待的“字段”,但不幸的是,在测试时,我需要多次访问它,这当然会在第二次访问时产生RuntimeError: cannot reuse already awaited coroutine

有现成的方法来模拟这样的异步属性吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-25 14:50:07

我能想到的最简单的方法是再次为bar修补async属性,以便进行测试。

我假设您在Foo上有其他要测试的方法,并且该方法调用它的bar

code.py

代码语言:javascript
复制
from asyncio import run


class Foo:
    @property
    async def bar(self) -> int:
        return 42

    async def func(self) -> int:
        return await self.bar


async def main():
    f = Foo()
    print(await f.func())


if __name__ == '__main__':
    run(main())

test.py

代码语言:javascript
复制
from unittest import IsolatedAsyncioTestCase
from unittest.mock import patch

from . import code


class FooTestCase(IsolatedAsyncioTestCase):
    async def test_func(self) -> None:
        expected_output = 69420

        @property
        async def mock_bar(_foo_self: code.Foo) -> int:
            return expected_output

        with patch.object(code.Foo, "bar", new=mock_bar):
            f = code.Foo()
            # Just to see that our mocking worked:
            self.assertEqual(expected_output, await f.bar)
            # Should call `bar` property again:
            output = await f.func()
        self.assertEqual(expected_output, output)

参考文献:patch docs.

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73844248

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档