【发布时间】:2022-12-07 00:15:53
【问题描述】:
我想弄清楚如何使用 @patch.object 来模拟一个函数,这里是 log.write(),它被导入但没有在模块的函数内部使用。这样的教程,https://www.pythontutorial.net/python-unit-testing/python-patch/
, 指出修补需要在使用它的目标,而不是它来自的地方。但是,使用的每个示例都显示了要在另一个函数中模拟的目标。在下面提到的用例中,记录器被导入并用于在函数范围之外写入日志。有没有办法模拟main.py 和routers.py 中的行为?
源代码/apis/main.py
from apis.routers import routes
from fastapi import FastAPI, Request
from starlette.background import BackgroundTask
from utils.log import Logger
app = FastAPI()
app.include_router(routers.router)
log = Logger(name="logger-1")
log.write("logger started")
@app.middleware("http")
async def add_process_time_header(request: Request, call_next: Any):
try:
response = await call_next(request)
except Exception as exc:
background = BackgroundTask(
log.write, message=f"Reason: error")
return JSONResponse(
status_code=500,
content={"reason": "error"},
background=background
)
return response
在 src/apis/routers/routes.py
from utils.log import Logger
from fastapi import APIRouter, BackgroundTask
router = APIRouter()
log = Logger(name="logger-1")
@router.get("/test")
def test(background_tasks: BackgroundTasks):
background_tasks.add_task(
log.write, message=f"Logging done.")
在 utils/log/logging.py 中
import logging
Class Logger:
def __init__(self, name):
# creates a logger
def write(self, message):
# writes log
【问题讨论】:
-
问题是代码在导入
main时已经执行,如果您尝试模拟它也是如此。避免这种情况(以及其他问题)的通常做法是将该初始化代码置于if __name__ == "__main__:"条件下。
标签: python unit-testing python-unittest python-mock python-unittest.mock