[英]Testing for MongoDB Functionality using Motor AsyncIO and Pytest
所以我正在嘗試編寫幾個測試來測試我使用異步 MongoDB 連接的函數。 為了連接到 MongoDB,我使用 Motor 和 asyncio。 我需要幫助模擬電機連接。
我的代碼:
公地.py
mongo = None
黑名單.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
主文件
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 一次並且所有后續測試都使用它,那就太好了。
您可以使用pytest-async-mongodb模擬異步 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
主文件
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()
黑名單.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
公地.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
黑名單.json
[
{
"_id": {"$oid": "60511d158f80a8d34986e2b0"},
"word" : "should_be_true"
}
]
夾具也可以是.yaml並且可以定義您想要的數量。 閱讀包文檔以獲取更多信息。
由於它已經過時,我創建了一個fork來更新它並使用新功能對其進行改進。 我們邀請您看一看它,如果您願意,可以使用它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.