【问题标题】:Python - mock function and assert exceptionPython - 模拟函数和断言异常
【发布时间】: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


【解决方案1】:

如果您想测试响应的状态代码和消息,您必须使用TestClient(app),其中app 是 FastAPI 应用程序。将异常转换为适当的响应是应用程序的任务,而不是路由器(这是您正在测试的)。

client = TestClient(app)

这样您就可以测试应用程序的 API(这是最有用的测试表面,恕我直言)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-04
    • 2013-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    相关资源
    最近更新 更多