Java+Rest Assured API测试中如何保存首次创建成功的productWorkingDate ID并用于删除操作
嘿,我碰到过类似的问题!你的核心痛点就是第二次创建失败时,响应里的productWorkingDate是null,导致你类级别的id被覆盖成了无效值(0),对吧?给你几个实用的解决方案,挑适合你场景的来用:
方案1:仅在创建成功时更新ID
在你提取ID的逻辑里加个判断,只有当响应里的productWorkingDate.id有效时,才覆盖原来的ID值。这样第二次创建失败时,无效的null/0就不会替换掉之前保存的有效ID了。
修改你的timeSlotsIsCreatedWithTheFollowingFields方法:
@And("^timeSlots is created with the following fields$") public void timeslotsIsCreatedWithTheFollowingFields(List<Map<String, String>> expectedTimeSlots) { // 原有构造请求体的逻辑保持不变 List<TimeSlots> listTimeSlots = new ArrayList<>(); for (Map<String, String> expectedTimeSlot : expectedTimeSlots) { TimeSlots timeSlots = new TimeSlots(); timeSlots.setDayOfWeek(expectedTimeSlot.get("dayOfWeek")); timeSlots.setStartTime(expectedTimeSlot.get("startTime")); timeSlots.setEndTime((expectedTimeSlot.get("endTime"))); timeSlots.setDuration(expectedTimeSlot.get("duration")); timeSlots.setQuantity(Integer.parseInt(expectedTimeSlot.get("quantity"))); timeSlots.setUsedQuantity(Integer.parseInt(expectedTimeSlot.get("usedQuantity"))); timeSlots.setActive(Boolean.parseBoolean(expectedTimeSlot.get("active"))); listTimeSlots.add(timeSlots); } productWorkingDate.setTimeSlots(listTimeSlots); root.setProductWorkingDate(productWorkingDate); String newProd = ObjectConverter.convertObjectToJson(root); commonData.response = NewProductEndPoints.createProductWorkingDates(newProd, cookies); // 新增判断:只有当响应返回有效ID时才更新 String newId = commonData.response.jsonPath().get("productWorkingDate.id"); if (newId != null && !newId.trim().isEmpty()) { id = newId; } }
方案2:拆分步骤,在成功验证后提取ID
这个方案更贴合Cucumber的行为驱动设计思路:把“提取ID”的逻辑放到创建成功验证的步骤里,只有当创建请求返回200状态码时,才去保存ID。
首先修改Then verify status code is 200的步骤定义,加入ID提取:
@Then("verify status code is 200") public void verifyStatusCodeIs200() { // 先验证状态码 Assert.assertEquals(200, commonData.response.getStatusCode()); // 验证成功后再提取并保存ID id = commonData.response.jsonPath().get("productWorkingDate.id"); }
然后把原来timeSlotsIsCreatedWithTheFollowingFields方法里的id = commonData.response.jsonPath().get("productWorkingDate.id");这一行删掉。
这样一来,第一次创建成功会走到这个Then步骤,保存有效ID;第二次创建失败不会触发这个步骤,ID就不会被覆盖,删除时自然用的是第一次的有效ID。
方案3:用标记位防止重复赋值
如果担心后续还有更多创建操作,你可以加一个类级别的布尔标记,确保ID只会被赋值一次:
// 类级别变量新增标记位 private static String id; private static boolean isIdSaved = false; @And("^timeSlots is created with the following fields$") public void timeslotsIsCreatedWithTheFollowingFields(List<Map<String, String>> expectedTimeSlots) { // 原有构造请求体的逻辑不变... commonData.response = NewProductEndPoints.createProductWorkingDates(newProd, cookies); // 仅当还没保存过ID,且当前响应有有效ID时才赋值 if (!isIdSaved) { String newId = commonData.response.jsonPath().get("productWorkingDate.id"); if (newId != null && !newId.trim().isEmpty()) { id = newId; isIdSaved = true; } } }
这个方案最保险,不管后续有多少次创建请求,只要第一次保存了有效ID,后面就再也不会更新它了。
小提示
另外,你可以把id的类型从默认的int改成String(看你的响应ID是字符串格式xl4W4jaj),避免null转成0的问题,这样更贴合实际的ID格式。
内容的提问来源于stack exchange,提问作者Qa Automation

