【发布时间】:2021-10-28 06:26:06
【问题描述】:
我使用 FastAPI 构建了一个与 DynamoDB 交互的 API。 在我的测试驱动开发之旅的开始,我对模拟什么有疑问。 这是get方法,main.py:
router = FastAPI()
@router.get("/{device_id}")
def get_data(request: Request, device_id: str, query: DataQuery = Depends(DataQuery.depends)):
da_service = DaService()
try:
start_time, end_time = DaService.validate_dates(query.start, query.end)
return 'OK'
except WrongDataFormat as e:
raise HTTPException(status_code=400, detail=str(e))
except Exception as e:
raise HTTPException(status_code=500, detail='Internal Server Error')
在我开始创建成功测试的测试文件中,test_main.py:
from fastapi.testclient import TestClient
from unittest import mock
from utils.exceptions import WrongDataFormat
from endpoints.datalake import router
client = TestClient(router)
def test_success_response():
with mock.patch('endpoints.datalake.DataApiService.get_datalake_data'):
response = client.get('/xxxxx', params = {'start': '1629886483', 'end': '1629886504'})
assert response.status_code == 200
assert isinstance(response.json(), dict)
现在我想为返回异常 WrongDataFormat 的时间创建测试,但我没有成功……这就是我现在所拥有的:
def test_exception_response_():
response = client.get('/xxxxx', params = {'2021-08-28', 'end': '2021-12-25'})
assert response.status_code == 400
如何模拟函数 main.validate_dates 以返回异常 WrongDataFormat 并正确断言?
【问题讨论】:
-
您要修补的是
da.validate_dates还是DaService.validate_dates?无论哪种方式,您可能想要修补DaService,以便您可以控制validate_dates的定义,或者更好的是,让get_data接收DaService-like 或DaService-like 的实例类,作为参数,完全避免使用mock.patch。 -
您似乎想为
validate_dates创建测试,而不是为端点创建测试;端点不会引发异常,它会返回 400 响应。编写一个测试以确保validate_dates引发异常,然后编写一个测试以确保您的端点在它发生时返回 400(小心模拟太多;突然间,您只是在测试您的模拟库是否有效,并且并不是说您的端点有意义)。模拟通常会创建对实现的依赖,而不是接口本身,这是您想要与之交互和测试的。 -
@chepner 据我了解,在补丁内部,它进入了函数的路径,而不是定义的地方......我没有得到你的建议,抱歉
-
@MatsLindh 感谢您的回复!要测试 400 validate_dates 需要返回 Exception,你会怎么做?
-
@Raphael 首先我会发送无效日期。什么是无效日期将由
validate_dates函数的作用来定义;这样你测试的是行为而不是实现,所以如果实现发生变化,你仍然有一个测试来确保你认为无效的日期仍然是一个测试。测试应该测试端点的需求而不是实现。如果你想使用模拟来生成异常,因为它看起来“更干净”(看起来是这样,但在我的经验中这是一个谬误),你做你所做的 - 但你不断言..
标签: python unit-testing testing python-unittest fastapi