test(api): 编写提交检测项接口的单元测试用例

- 实现提交检测项接口正常提交的多种场景测试,包括全部合格和部分不合格样本
- 添加带图片和带备注的样本提交测试,验证相关字段能正常保存
- 增加更新已有检验记录的测试,覆盖保存和更新逻辑
- 包含任务ID、物料编号、样本数量、合格数量、不合格数量等参数为空时的校验失败测试
- 测试检验项列表为空或为null的参数校验情况
- 验证检验项中的检验标准项内容ID和样本列表的非空校验
- 测试样本中是否合格字段为空时的校验失败
- 支持一次提交多个检验项,每项包含多个样本数据的测试
- 验证空请求体时接口的参数解析和校验结果
- 编写辅助方法构建有效请求体和检验项及样本数据,提高测试代码复用性
This commit is contained in:
曹鹏飞 2026-04-25 14:36:42 +08:00
parent 5464981d5f
commit 7b95137a81
1 changed files with 393 additions and 0 deletions

View File

@ -0,0 +1,393 @@
package com.nflg.qms.admin;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONUtil;
import com.nflg.wms.common.pojo.ApiResult;
import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO;
import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitItemQO;
import com.nflg.wms.common.pojo.qo.QmsIncomingInspectionTaskTodoCheckSubmitQO;
import com.nflg.wms.common.pojo.vo.FileUploadVO;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestMethodOrder;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 提交检测项addCheckItem接口测试
* <p>
* 测试前提
* 1. qms-admin 服务已启动默认 http://localhost:8105
* 2. 测试账号已登录将有效的 token 填入 TOKEN 常量
* 3. 数据库中存在有效的任务IDVALID_TASK_ID和对应的物料唯一编号VALID_MATERIAL_UNIQUE_NO
* 4. VALID_STANDARD_ITEM_CONTENT_ID 对应数据库中已存在的检验标准项内容ID
* </p>
*/
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class QmsIncomingInspectionTaskApiTest {
// ===================== 配置区 =====================
/** 服务地址 */
private static final String BASE_URL = "http://localhost:8105";
/** 当前登录用户的 token */
private static final String TOKEN = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOjEsInJuU3RyIjoiU0VxNWhlcXdHOERvVTBkeWFLZnZDbW1FTGFuek5jQlMiLCJuYW1lIjoi6LaF57qn566h55CG5ZGYIiwiY29kZSI6ImFkbWluIiwicm9sZXMiOlsiU3VwZXJBZG1pbiJdLCJ0eXBlIjoxfQ.wuEnMU5vJSqh2vr69MKooFUHD04-_-86eeJee_2zir4";
/** 有效的任务ID */
private static final Long VALID_TASK_ID = 2046829044461977601L;
/** 有效的物料唯一编号 */
private static final String VALID_MATERIAL_UNIQUE_NO = "MAT_UNIQUE_001";
/** 有效的检验标准项内容ID */
private static final Long VALID_STANDARD_ITEM_CONTENT_ID = 2047511371773046785L;
// ===================== 配置区结束 =====================
// ==================== HTTP 工具方法 ====================
private static <T> ApiResult<T> post(String path, Object body, TypeReference<ApiResult<T>> typeRef) {
String url = BASE_URL + path;
String reqBody = body == null ? "" : JSONUtil.toJsonStr(body);
HttpResponse resp = HttpRequest.post(url)
.header("authorization", TOKEN)
.header("Content-Type", "application/json")
.body(reqBody)
.execute();
String raw = resp.body();
System.out.println("[POST] " + path);
System.out.println(" 请求: " + reqBody);
System.out.println(" 响应: " + raw);
return JSONUtil.toBean(raw, typeRef, false);
}
private static <T> void assertSuccess(ApiResult<T> result, String msg) {
Assert.isTrue(result != null && result.getCode() == 200,
() -> new RuntimeException(msg + " => " + JSONUtil.toJsonStr(result)));
}
private static void assertFailed(ApiResult<?> result, String msg) {
Assert.isTrue(result != null && result.getCode() != 200,
() -> new RuntimeException(msg + " => 预期失败但实际成功"));
}
// ==================== 提交检测项接口测试 ====================
/**
* 提交检测项正常提交所有样本合格
* 验证点
* 1. 接口返回成功
* 2. inspectionQty == qualifiedQty记录应标记为合格
*/
@Test
@Order(1)
public void test01_addCheckItem_Success_AllQualified() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setQualifiedQty(5);
request.setUnqualifiedQty(0);
request.setInspectionQty(5);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertSuccess(result, "提交检测项(全部合格)失败");
System.out.println(" ✅ 提交检测项(全部合格)成功");
}
/**
* 提交检测项正常提交存在不合格样本
* 验证点
* 1. 接口返回成功
* 2. qualifiedQty < inspectionQty记录应标记为不合格
*/
@Test
@Order(2)
public void test02_addCheckItem_Success_PartialUnqualified() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setQualifiedQty(3);
request.setUnqualifiedQty(2);
request.setInspectionQty(5);
// 不合格样本设置 qualified=false
QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO unqualifiedData =
buildItemData(false, new BigDecimal("9.5"), Collections.emptyList());
request.getItems().get(0).getDatas().add(unqualifiedData);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertSuccess(result, "提交检测项(含不合格样本)失败");
System.out.println(" ✅ 提交检测项(含不合格样本)成功");
}
/**
* 提交检测项带图片的样本提交
* 验证点图片ID能正常保存到检验数据记录
*/
@Test
@Order(3)
public void test03_addCheckItem_Success_WithImages() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
FileUploadVO image = new FileUploadVO(100L, "test_image.jpg", "http://example.com/test_image.jpg");
request.getItems().get(0).getDatas().get(0).setImages(List.of(image));
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertSuccess(result, "带图片提交检测项失败");
System.out.println(" ✅ 带图片提交检测项成功");
}
/**
* 提交检测项带备注的检验项提交
* 验证点备注字段能正常保存
*/
@Test
@Order(4)
public void test04_addCheckItem_Success_WithRemark() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.getItems().get(0).setRemark("外观轻微划痕,不影响功能");
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertSuccess(result, "带备注提交检测项失败");
System.out.println(" ✅ 带备注提交检测项成功");
}
/**
* 提交检测项更新已有检验记录传入已有ID
* 验证点 id 不为 null 接口执行 saveOrUpdate 逻辑更新已有记录
*/
@Test
@Order(5)
public void test05_addCheckItem_Success_UpdateExisting() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setId(1L); // 已存在的记录ID根据实际环境替换
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertSuccess(result, "更新已有检验记录失败");
System.out.println(" ✅ 更新已有检验记录成功");
}
/**
* 提交检测项任务ID为空
* 验证点接口返回参数校验错误@NotNull 校验
*/
@Test
@Order(6)
public void test06_addCheckItem_Fail_TaskIdNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setTaskId(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "任务ID为空应返回失败");
System.out.println(" ✅ 任务ID为空校验通过");
}
/**
* 提交检测项物料唯一编号为空
* 验证点接口返回参数校验错误@NotNull 校验
*/
@Test
@Order(7)
public void test07_addCheckItem_Fail_MaterialUniqueNoNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setMaterialUniqueNo(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "物料唯一编号为空应返回失败");
System.out.println(" ✅ 物料唯一编号为空校验通过");
}
/**
* 提交检测项样本数量为空
* 验证点接口返回参数校验错误@NotNull 校验
*/
@Test
@Order(8)
public void test08_addCheckItem_Fail_InspectionQtyNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setInspectionQty(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "样本数量为空应返回失败");
System.out.println(" ✅ 样本数量为空校验通过");
}
/**
* 提交检测项合格数量为空
* 验证点接口返回参数校验错误@NotNull 校验
*/
@Test
@Order(9)
public void test09_addCheckItem_Fail_QualifiedQtyNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setQualifiedQty(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "合格数量为空应返回失败");
System.out.println(" ✅ 合格数量为空校验通过");
}
/**
* 提交检测项不合格数量为空
* 验证点接口返回参数校验错误@NotNull 校验
*/
@Test
@Order(10)
public void test10_addCheckItem_Fail_UnqualifiedQtyNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setUnqualifiedQty(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "不合格数量为空应返回失败");
System.out.println(" ✅ 不合格数量为空校验通过");
}
/**
* 提交检测项检验项列表为空
* 验证点接口返回参数校验错误@NotEmpty 校验
*/
@Test
@Order(11)
public void test11_addCheckItem_Fail_ItemsEmpty() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setItems(Collections.emptyList());
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "检验项列表为空应返回失败");
System.out.println(" ✅ 检验项列表为空校验通过");
}
/**
* 提交检测项检验项列表为null
* 验证点接口返回参数校验错误@NotEmpty 校验
*/
@Test
@Order(12)
public void test12_addCheckItem_Fail_ItemsNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.setItems(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "检验项列表为null应返回失败");
System.out.println(" ✅ 检验项列表为null校验通过");
}
/**
* 提交检测项检验项中检验标准项内容ID为空
* 验证点接口返回参数校验错误@NotNull 级联校验
*/
@Test
@Order(13)
public void test13_addCheckItem_Fail_ItemContentIdNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.getItems().get(0).setInspectionStandardItemContentId(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "检验标准项内容ID为空应返回失败");
System.out.println(" ✅ 检验标准项内容ID为空校验通过");
}
/**
* 提交检测项检验项的样本列表为空
* 验证点接口返回参数校验错误@NotEmpty 级联校验
*/
@Test
@Order(14)
public void test14_addCheckItem_Fail_ItemDatasEmpty() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.getItems().get(0).setDatas(Collections.emptyList());
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "样本列表为空应返回失败");
System.out.println(" ✅ 样本列表为空校验通过");
}
/**
* 提交检测项样本中是否合格字段为空
* 验证点接口返回参数校验错误@NotNull 级联校验
*/
@Test
@Order(15)
public void test15_addCheckItem_Fail_DataQualifiedNull() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
request.getItems().get(0).getDatas().get(0).setQualified(null);
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertFailed(result, "是否合格字段为空应返回失败");
System.out.println(" ✅ 是否合格字段为空校验通过");
}
/**
* 提交检测项多个检验项提交
* 验证点可以一次提交多个检验项每项下有多个样本数据
*/
@Test
@Order(16)
public void test16_addCheckItem_Success_MultipleItems() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = buildValidRequest();
QmsIncomingInspectionTaskTodoCheckSubmitItemQO item2 = buildItem(VALID_STANDARD_ITEM_CONTENT_ID + 1, null);
request.setItems(new ArrayList<>(List.of(request.getItems().get(0), item2)));
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", request, new TypeReference<>() {});
assertSuccess(result, "多个检验项提交失败");
System.out.println(" ✅ 多个检验项提交成功");
}
/**
* 提交检测项请求体为空无请求体
* 验证点接口返回参数解析或校验错误
*/
@Test
@Order(17)
public void test17_addCheckItem_Fail_EmptyBody() {
ApiResult<Void> result = post("/incoming-inspection-task/pad/add-check-item", null, new TypeReference<>() {});
assertFailed(result, "空请求体应返回失败");
System.out.println(" ✅ 空请求体校验通过");
}
// ==================== 辅助方法 ====================
/**
* 构建一个有效的提交检测项请求
*/
private QmsIncomingInspectionTaskTodoCheckSubmitQO buildValidRequest() {
QmsIncomingInspectionTaskTodoCheckSubmitQO request = new QmsIncomingInspectionTaskTodoCheckSubmitQO();
request.setTaskId(VALID_TASK_ID);
request.setMaterialUniqueNo(VALID_MATERIAL_UNIQUE_NO);
request.setInspectionQty(5);
request.setQualifiedQty(5);
request.setUnqualifiedQty(0);
request.setItems(new ArrayList<>(List.of(buildItem(VALID_STANDARD_ITEM_CONTENT_ID, null))));
return request;
}
/**
* 构建一个检验项
*
* @param contentId 检验标准项内容ID
* @param remark 备注可为null
*/
private QmsIncomingInspectionTaskTodoCheckSubmitItemQO buildItem(Long contentId, String remark) {
QmsIncomingInspectionTaskTodoCheckSubmitItemQO item = new QmsIncomingInspectionTaskTodoCheckSubmitItemQO();
item.setInspectionStandardItemContentId(contentId);
item.setRemark(remark);
item.setDatas(new ArrayList<>(List.of(buildItemData(true, new BigDecimal("10.5"), Collections.emptyList()))));
return item;
}
/**
* 构建一个样本数据
*
* @param qualified 是否合格
* @param measuredValue 测量值可为null
* @param images 图片列表
*/
private QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO buildItemData(
Boolean qualified, BigDecimal measuredValue, List<FileUploadVO> images) {
QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO data =
new QmsIncomingInspectionTaskTodoCheckSubmitItemDataQO();
data.setQualified(qualified);
data.setMeasuredValue(measuredValue);
data.setImages(images);
return data;
}
}