如何在Behave测试中验证Python函数已调用指定API端点(不修改返回值)
验证tracking-service请求的Behave测试方案
问题背景
编写Behave测试时,需要验证order_product函数是否正确调用了http://tracking-service/addorder接口,同时不能修改order_product的返回值(仅返回order-api的响应)。
解决方案:使用unittest.mock拦截请求
核心思路是通过unittest.mock.patch拦截requests.post调用,记录所有请求参数,后续验证是否包含对目标URL的调用。
步骤1:导入mock模块
在steps文件开头添加:
from unittest.mock import patch, call, Mock
步骤2:修改When步骤,拦截并记录请求
修改ordering_product函数,用patch包裹order_product的调用,模拟请求返回值,并把mock对象存入context:
@when("I order a product") def ordering_product(context): with patch('requests.post') as mock_post: # 按调用顺序模拟两个post请求的返回值 # 第一个是tracking-service的响应(原函数不使用该返回,只需模拟合法响应) # 第二个是order-api的响应,需匹配原函数返回结构,确保能正确提取order_id mock_post.side_effect = [ Mock(status_code=200), Mock(status_code=200, json=lambda: {'order_id': 'test_order_123'}) ] # 调用原函数,获取order-api响应并提取order_id order_response = order_product() context.order_id = order_response.json()['order_id'] # 将mock对象存入context,供后续验证使用 context.mock_post = mock_post
步骤3:实现Then步骤的验证逻辑
在forwarded_to_tracker函数中,检查mock记录的调用参数是否包含目标请求:
@then("the order is forwarded to the tracker service") def forwarded_to_tracker(context): # 构造预期的调用参数(需与order_product中的调用一致) expected_order_body = create_order_body() expected_call = call("http://tracking-service/addorder", data=expected_order_body) # 验证该调用是否存在于mock的调用列表中 assert expected_call in context.mock_post.call_args_list, "未向tracking-service发起请求"
注意事项
- 如果
create_order_body函数返回值不固定,建议同时mock该函数,确保测试稳定性:with patch('your_module.create_order_body') as mock_create_body: mock_create_body.return_value = {'product_id': '1', 'quantity': 2} # 后续的patch和调用逻辑 side_effect的顺序必须与order_product中requests.post的调用顺序完全一致,否则会导致模拟错误。
内容的提问来源于stack exchange,提问作者Alan
相关产品推荐
相关产品推荐

