Wiremock多场景下有状态行为不符合预期问题排查
我有一个测试辅助函数createUser,它会向后端API发起HTTP请求创建用户。后端API调用Auth0客户端的方法创建用户,我已为Auth0客户端的URL路径/api/v2/users配置了Wiremock响应。
我正在测试的服务包含两种用户类型:账户所有者和受邀用户。在所有测试执行前,我会两次调用该辅助函数:
const owner = await createUser('owner@email.com'); const invitee = await createUser('invitee@email.com');
预期owner的邮箱为owner@email.com,invitee的邮箱为invitee@email.com。
为了让Wiremock返回两种不同响应,我使用了Wiremock场景功能,当前响应配置如下:
用户#1(所有者用户响应配置)
{ "scenarioName": "user-scenario", "requiredScenarioState": "Started", "newScenarioState": "owner-user", "request": { "method": "POST", "urlPattern": "/api/v2/users" }, "response": { "status": 201, "headers": { "Content-Type": "application/json" }, "jsonBody": { "email": "owner@email.com" } } }
用户#2(受邀用户响应配置)
{ "scenarioName": "user-scenario", "requiredScenarioState": "owner-user", "request": { "method": "POST", "urlPattern": "/api/v2/users" }, "response": { "status": 201, "headers": { "Content-Type": "application/json" }, "jsonBody": { "email": "invitee@email.com" } } }
运行测试时,Wiremock对两次createUser调用均返回第二个响应。由于第二个响应是后创建的,Wiremock会优先使用最新创建的响应。我尝试给第一个响应设置priority: 1来强制返回它并切换场景状态,但仅首次测试运行时有效,后续运行失效。有时删除Wiremock Docker镜像并重启容器后能符合预期,但之后又会回到两次都返回第二个响应的状态。
请问我哪里配置错误?如果不是场景配置问题,还有哪些可能导致这种不一致的原因?
一、场景配置的核心问题
1. 场景状态未重置
Wiremock的场景状态默认是持久化的(存储在内存或文件中),若测试结束后未重置场景状态,下一次测试运行时场景状态可能停留在owner-user,导致第一个请求直接匹配到第二个响应配置。
解决措施:
- 在测试套件执行前,调用Wiremock的
POST /__admin/scenarios/user-scenario/reset接口重置指定场景的状态; - 启动Wiremock时添加
--reset-mappings参数,确保每次启动都重置所有映射规则和场景状态; - 若使用Docker运行Wiremock,避免挂载本地目录存储映射或状态数据,或每次启动容器时重新初始化映射配置。
2. 优先级配置不完整
仅给第一个响应设置priority: 1,但第二个响应默认优先级为5。当场景状态已处于owner-user时,第一个规则的requiredScenarioState不匹配,仍会触发第二个规则。若测试前场景状态未重置,首次请求就会匹配第二个规则,导致场景状态无法按预期切换。
正确做法:给两个规则都配置明确的优先级(例如第一个设priority: 1,第二个设priority: 2),同时严格保证测试前重置场景状态。
二、其他可能的原因
1. Docker容器状态持久化
若Docker运行Wiremock时挂载了本地目录存储映射或状态,容器重启时会保留之前的场景状态,导致测试结果不一致。需取消本地目录挂载,或启动容器时执行状态重置命令。
2. 测试并发干扰
若测试用例并发执行,多个测试同时修改场景状态会导致状态混乱。需确保测试串行执行,或每个测试用例独立重置场景状态。
3. 映射加载顺序异常
若映射文件按文件名顺序加载,且两个规则的请求匹配模式完全一致,优先级相同的情况下后加载的规则会覆盖先加载的。需通过明确的优先级配置避免这种情况。
内容的提问来源于stack exchange,提问作者buterfly85

