为什么我的模拟未对以下补丁函数返回True?
在我的 get_orders.py
文件中,我导入了一个叫 admin_only
的函数,这个函数在指定的路径下(src.lib.authorization
)。在我的 test_get_orders.py
文件里,我想要对这个函数进行“修补”,但是这个函数没有被修补。当我运行 pytest 时,它试图调用这个函数的实际代码,而不是返回 True。这是为什么呢?我该怎么解决这个问题?另外,还要提到的是,get_orders.py
文件位于 src/routes/get_orders.py
这个路径下。
# get_orders.py
import boto3
import os
from fastapi import APIRouter, Depends
from aws_lambda_powertools import Logger
from fastapi.exceptions import HTTPException
from src.models import Order
from src.lib.dynamodb import DynamoConnection
from src.lib.response import fastapi_gateway_response
from src.lib.authorization import admin_only
logger = Logger()
router = APIRouter()
orders_table = DynamoConnection(
os.environ.get("DYNAMODB_REGION", "us-east-1"),
os.environ.get("DYNAMODB_ENDPOINT_URL", None),
os.environ.get("DYNAMODB_ORDERS_TABLE_NAME", "orders"),
).table
@logger.inject_lambda_context
@router.get(
"/orders",
status_code=200,
dependencies=[Depends(admin_only)],
)
def get_orders():
logger.info(f"Getting orders")
dynamo_response = orders_table.scan()
if "Items" not in dynamo_response:
raise HTTPException(status_code=404, detail="No orders found")
orders = [Order(**o).clean() for o in dynamo_response.get("Items")]
logger.info(f"Returning {len(orders)} orders")
return fastapi_gateway_response(200, {}, orders)
#test_get_orders.py
import pytest
import logging
from unittest.mock import patch
from freezegun import freeze_time
from botocore.stub import Stubber
from fastapi.testclient import TestClient
from src.api import app
from src.routes.get_orders import orders_table
logger = logging.getLogger()
test_client = TestClient(app, headers={"Authorization": "Bearer TOKEN"})
@pytest.fixture(autouse=True, scope="function")
def orders_dynamodb_stub():
with Stubber(orders_table.meta.client) as ddb_stubber:
yield ddb_stubber
ddb_stubber.assert_no_pending_responses()
@freeze_time("2024-03-22 12:00:00")
@patch("src.routes.get_orders.admin_only", return_value=True)
def test_handler_valid_event_get_orders(orders_dynamodb_stub):
orders_dynamodb_stub.add_response(
"scan",
{
"Items": [
{
"order_id": {"S": "ORDER-1"},
"dessert_id": {"S": "DESSERT-1"},
"dessert_name": {"S": "Chocolate Cake"},
"quantity": {"N": "1"},
"customer_first_name": {"S": "jane"},
"customer_last_name": {"S": "doe"},
"customer_email": {"S": "jane.doe@gmail.com"},
"customer_phone_number": {"S": "555-555-5555"},
"customer_zip_code": {"S": "90210"},
"delivery_address": {"S": "123 Main St, Los Angeles, CA 90210"},
"scheduled_delivery_time": {"N": "1711108800"},
"order_total": {"N": "10.00"},
"order_status": {"S": "NEW"},
"order_date": {"N": "1711108800"},
},
],
},
expected_params={"TableName": "orders"},
)
response = test_client.get("/v1/orders")
pytest.helpers.assert_responses_equal(
response,
200,
[
{
"order_id": "ORDER-1",
"dessert_id": "DESSERT-1",
"dessert_name": "Chocolate Cake",
"quantity": 1,
"customer_first_name": "jane",
"customer_last_name": "doe",
"customer_email": "jane.doe@gmail.com",
"customer_phone_number": "555-555-5555",
"customer_zip_code": "90210",
"delivery_address": "123 Main St, Los Angeles, CA 90210",
"scheduled_delivery_time": 1711108800,
"order_total": 10.00,
"order_status": "NEW",
"order_date": 1711108800,
}
],
)
2 个回答
0
在这一行
@patch("src.routes.get_orders.admin_only", return_value=True)
你正在尝试从 src.routes.get_orders
调用这个函数
@patch("src.lib.authorization.admin_only", return_value=True)
这样做应该没问题。
1
因为 admin_only
是在一个依赖关系中使用的,所以在启动模块的时候会传递这个引用,这意味着如果你尝试修改它是没有效果的。解决这个问题的方法是使用 FastAPI 的 依赖覆盖。可以像这样做:
@freeze_time("2024-03-22 12:00:00")
def test_handler_valid_event_get_orders(orders_dynamodb_stub):
app.dependency_overrides[admin_only] = lambda *args, **kargs: True)
# Run your test
app.dependency_overrides = {}