ousaa / mercado-libre
description
v0.3.16
2026-07-22 02:05 UTC
Requires
- php: >=7.4
- ext-json: *
- guzzlehttp/guzzle: ^6.0 || ^7.0
Requires (Dev)
- phpunit/phpunit: ^9.6
README
暂时只有少部分接口。
单元测试规范
基本要求
- 使用 PHPUnit,项目最低兼容 PHP 7.4;涉及请求核心、类型声明或兼容性调整时,必须至少使用 PHP 7.4 完整运行一次测试。
- 单元测试禁止请求真实的 MercadoLibre API。HTTP 请求统一使用 Guzzle MockHandler、history middleware、Spy 或 Fake,保证测试可重复、无网络依赖。
- 测试必须验证最终交给 Guzzle 的 PSR-7 Request 或请求 options,不能只断言 SDK 对象中的
headers、accessToken等中间状态。 - 修复缺陷时必须先补对应的回归测试,确认测试在旧实现下能够复现问题,再修改实现直至测试通过。
- 测试之间不得共享可变状态;每个测试自行创建
MercadoLibre、MercadoLibreApi、Guzzle Client、MockHandler 和请求记录容器。
测试目录
测试目录直接对应 src/ 下的相对路径,不额外划分 Unit/、Feature/:
src/ApiUtils.php -> tests/ApiUtilsTest.php
src/MercadoLibre.php -> tests/MercadoLibreTest.php
src/MercadoLibreApi.php -> tests/MercadoLibreApiTest.php
src/ApiModules/User.php -> tests/ApiModules/UserTest.php
src/ApiModules/UserProduct.php -> tests/ApiModules/UserProductTest.php
测试文件名统一为被测类名加 Test。
命名与注释
- 测试方法使用三段式命名:
test[目标方法]_[场景]_[预期结果]。 - 测试类声明上方必须添加中文 DocBlock,说明该测试类覆盖的范围。
- 每个测试方法声明上方必须添加中文 DocBlock,用一句话说明业务场景和预期结果。
- 测试代码按“准备数据、执行行为、断言结果”三段组织;场景复杂时可以用空行分隔,不添加重复代码含义的行内注释。
示例:
/** MercadoLibre API 请求头隔离测试 */
class MercadoLibreApiTest extends TestCase
{
/** 连续请求不同账号时,每次请求都应使用当前账号的 Authorization */
public function testHttpRequest_WithDifferentAccounts_ShouldUseCurrentAccessToken(): void
{
// 准备数据
// 执行行为
// 断言最终发送的 PSR-7 Request
}
}
HTTP 请求测试要求
请求层测试至少需要断言以下内容中与场景相关的部分:
- 最终请求 URL、HTTP method、query、body。
- 最终请求中的
Authorization、Accept、Content-Type和接口专用 header。 - 请求完成后,默认 header、临时 header、响应和错误状态是否正确隔离或恢复。
- 连续请求、交替请求和批量请求不能复用上一条请求的动态 header 或 options。
- Header 名称按 HTTP 语义大小写不敏感;测试应覆盖不同大小写的同名 header,防止产生重复或错误覆盖。
请求隔离回归测试
MercadoLibre、MercadoLibreApi 和底层 Guzzle Client 调整为实例独立后,必须覆盖以下场景:
- 两个
MercadoLibre实例分别持有不同的MercadoLibreApi和 Guzzle Client,任何可变状态都不共享。 - 连续请求两个账号时,最终发送的 Authorization 分别使用各自账号的 access token。
- 同一实例刷新 access token 后,下一次请求立即使用新 token,不得复用旧 token。
httpRequestJson()后调用httpRequestRes(),后者不得继承 JSON 请求产生的Accept、Content-Type或其他临时 header。httpRequestRes()后调用httpRequestJson(),JSON 请求应正确添加自己的Accept和Content-Type,且不影响后续请求。- JSON 请求带空数组、空对象或字符串
"0"等有效 body 时,仍应正确编码并设置Content-Type。 - 调用方传入的单次请求 header、SDK 默认 header、JSON header 和 Authorization 必须按照明确的优先级合并,不能出现同名 header 重复或旧值覆盖当前值。
withTemporaryHeaders()在正常返回和抛出异常时都必须恢复原始 header。requestMulti()中每个 item 的 query、body、timeout、headers 和 Authorization 相互独立,前一项不能污染后一项。- JSON 批量请求仅给对应 item 添加
Accept、Content-Type,调用结束后不能污染普通单请求或后续批量请求。 - 不同实例的 response、message、error content、error JSON 和批量响应集合互不影响。
断言原则
- 优先断言明确值,不只使用
assertNotEmpty()、assertTrue()等宽泛断言。 - Authorization 回归测试必须比较最终请求头完整值,确保不是只验证当前对象保存的 token。
- Header 隔离测试必须同时断言“当前请求应该存在”和“后续请求不应该存在”。
- 批量请求至少准备两个差异明显的 item,以确认 options 没有跨 item 残留。
- 异常场景需要断言异常类型,并检查错误响应状态不会污染其他实例。
运行测试
composer install
php ./vendor/bin/phpunit
运行单个测试文件:
./vendor/bin/phpunit tests/MercadoLibreApiTest.php