gpt4 book ai didi

python - 使用 Motor AsyncIO 和 Pytest 测试 MongoDB 功能

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

所以我试图编写几个测试来测试我使用异步 MongoDB 连接的函数。为了连接到 MongoDB,我使用 Motor 和 asyncio。我需要帮助模拟电机连接。
我的代码:
commons.py

mongo = None
blacklist.py
import commons

class Blacklist(object):
async def check_if_blacklisted(self, word: str):
blacklisted = False
if await commons.mongo.dbtest.blacklist.find_one({'word': word}):
blacklisted = True
return blacklisted
main.py
import asyncio
from blacklist import Blacklist
from motor.motor_asyncio import AsyncIOMotorClient
import commons

async def run():
commons.mongo = AsyncIOMotorClient("mongodb://localhost", io_loop=asyncio.get_event_loop())
blacklist_checker = Blacklist()
result = await blacklist_checker.check_if_blacklisted(word="should_be_false")
print(result)
# > False

result = await blacklist_checker.check_if_blacklisted(word="should_be_true")
print(result)
# > True

loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
我现在想通过模拟电机连接来测试 blacklist.py,但我似乎无法正常运行测试。以下是我尝试过的代码:
test_blacklist.py
import pytest
from blacklist import Blacklist

class TestBlacklist(object):

@pytest.fixture
async def motor(self, event_loop):
# I know I'm not mocking the Motor Connection here,
# but just wanted to show you the output using this fixture.
commons.mongo = motor.motor_asyncio.AsyncIOMotorClient(io_loop=event_loop)
yield commons.mongo
commons.mongo.close()

@pytest.mark.asyncio
async def test_check_if_blacklisted(self):
blacklist_checker = Blacklist()
blacklisted = await blacklist_checker.check_if_blacklisted(word="should_be_false")
assert blacklisted == False
# > AttributeError: 'NoneType' object has no attribute 'blacklist'
pytest-mongodb:
import pytest
from unittest.mock import patch
from blacklist import Blacklist

class TestBlacklist(object):

@pytest.mark.asyncio
async def test_check_if_blacklisted(self, mongodb):
with patch("blacklist.commons.mongo") as db:
db = mongodb
blacklist_checker = Blacklist()
blacklisted = await blacklist_checker.check_if_blacklisted(word="should_be_false")
assert blacklisted == False
# > TypeError: object MagicMock can't be used in 'await' expression
我尝试在线搜索,但找不到合适的线程来帮助我在模拟异步电机连接时执行测试。此外,如果您认为我的测试方向不正确,请告诉我,因为我是编写测试的新手,尤其是异步数据库连接。
注: blacklist.py 有各种需要 MongoDB 功能的函数,所以如果在我的 test_blacklist.py 中我可以只初始化 commons.mongo 一次并且所有后续测试都使用它,那就太好了。

最佳答案

您可以使用 模拟异步 MongoDB 数据库pytest-async-mongodb 但请记住,它已过时且存在依赖项错误,因此您必须按以下方式修复依赖项版本:

mongomock==3.12.0
pyyaml==3.13
pytest-asyncio==0.10.0
pytest==3.6.4
pytest-async-mongodb 您可以通过添加一个名为 async_mongodb 的参数来获取测试中的模拟数据库。
我会让你的代码和结构。
project
-app
__init__.py
blacklist.py
commons.py
-test
-fixtures
blacklist.json
__init__.py
test_blacklist.py
main.py
pytest.ini
main.py
import asyncio
from app.blacklist import Blacklist
from app.commons import get_database, set_client
from motor.motor_asyncio import AsyncIOMotorClient


async def run():
set_client(
AsyncIOMotorClient("mongodb://localhost", io_loop=asyncio.get_event_loop())
)
db = await get_database()
blacklist_checker = Blacklist()
result = await blacklist_checker.check_if_blacklisted(db, word="should_be_false")
print(result)
# > False

result = await blacklist_checker.check_if_blacklisted(db, word="should_be_true")
print(result)
# > True


loop = asyncio.get_event_loop()
loop.run_until_complete(run())
loop.close()
blacklist.py
from motor.motor_asyncio import AsyncIOMotorDatabase


class Blacklist(object):
async def check_if_blacklisted(self, db: AsyncIOMotorDatabase, word: str):
blacklisted = False
if await db.blacklist.find_one({"word": word}):
blacklisted = True
return blacklisted
commons.py
from motor.motor_asyncio import AsyncIOMotorClient, AsyncIOMotorDatabase


class DataBase:
client: AsyncIOMotorClient = None


db = DataBase()


async def get_database() -> AsyncIOMotorDatabase:
return db.client["dbtest"]


def set_client(client):
db.client = client
test_blacklist.py
import pytest
from app import blacklist


@pytest.mark.asyncio
async def test_should_be_false(async_mongodb):
blacklist_checker = blacklist.Blacklist()
blacklisted = await blacklist_checker.check_if_blacklisted(
async_mongodb, word="should_be_false"
)
assert blacklisted == False


@pytest.mark.asyncio
async def test_should_be_true(async_mongodb):
blacklist_checker = blacklist.Blacklist()
blacklisted = await blacklist_checker.check_if_blacklisted(
async_mongodb, word="should_be_true"
)
assert blacklisted == True
pytest.ini
[pytest]
async_mongodb_fixture_dir =
test/fixtures

async_mongodb_fixtures =
blacklist
blacklist.json
[
{
"_id": {"$oid": "60511d158f80a8d34986e2b0"},
"word" : "should_be_true"
}
]
fixture 也可以是 .yaml 并且可以定义您想要的数量。阅读 package documentation想要查询更多的信息。
由于已经过时,我创建了一个 fork更新它并使用新功能改进它。我们邀请您看一看它,并根据需要使用它。

关于python - 使用 Motor AsyncIO 和 Pytest 测试 MongoDB 功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63889494/

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