test(doc): 更新图片篡改检测控制器测试

- 移除原有的单元测试类和mock逻辑
- 添加集成测试替代原有单元测试
- 使用真实接口调用验证功能
- 增加在线图片检测验证
- 添加完整的参数测试覆盖
- 集成百度API的实际调用测试
- 添加详细的测试结果输出和结论显示
This commit is contained in:
zhengli 2026-05-28 13:48:24 +08:00
parent c08d775056
commit 202b951377

View File

@ -1,222 +1,76 @@
package com.heyu.api.controller.doc;
import com.heyu.api.baidu.handle.doc.BForgeryDetectionHandle;
import com.heyu.api.baidu.request.doc.BForgeryDetectionRequest;
import com.heyu.api.baidu.response.doc.BForgeryDetectionResp;
import com.heyu.api.data.utils.ApiR;
import com.ApiInterfaceApplicationTests;
import com.alibaba.fastjson.JSON;
import com.heyu.api.data.utils.R;
import com.heyu.api.request.doc.ForgeryDetectionRequest;
import com.heyu.api.resp.doc.ForgeryDetectionResp;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
/**
* ForgeryDetectionController 单元测试
* 图片篡改检测 - 在线图片验证
*
* 调用本地 /doc/forgeryDetection 接口验证目标图片是否被篡改
*
* 假设(Given): 目标图片可访问百度 API 可用
* (When): 调用 forgeryDetection 接口所有参数开启
* (Then): 返回检测结果
*
* @author zhengli
* @since 20260528_zl
*/
public class ForgeryDetectionControllerTest {
public class ForgeryDetectionControllerTest extends ApiInterfaceApplicationTests {
@InjectMocks
private ForgeryDetectionController controller;
@Autowired
private ForgeryDetectionController forgeryDetectionController;
@Mock
private BForgeryDetectionHandle bForgeryDetectionHandle;
@BeforeEach
public void setUp() {
MockitoAnnotations.initMocks(this);
}
// ========== 正常流程测试 ==========
private static final String TARGET_IMAGE_URL = "https://www.opsky.com.cn/upload/20211224/KXfgvm2MFRAXKbPu5LK.png";
@Test
public void forgeryDetectionSuccessTest() {
void forgeryDetectionAllParamsTest() {
// 1. 构造请求 - 所有参数开启
ForgeryDetectionRequest request = new ForgeryDetectionRequest();
request.setImageBase64("base64ImageData");
BForgeryDetectionResp bResp = new BForgeryDetectionResp();
BForgeryDetectionResp.ResultDTO result = new BForgeryDetectionResp.ResultDTO();
result.setDetectionResult("fake");
result.setTamperedProportion(0.85);
bResp.setResult(result);
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenReturn(ApiR.setData(bResp));
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
assertNotNull(r);
assertEquals("200", r.getCode());
ForgeryDetectionResp resp = r.getData();
assertNotNull(resp);
assertEquals("fake", resp.getDetectionResult());
assertEquals(Double.valueOf(0.85), resp.getTamperedProportion());
}
@Test
public void forgeryDetectionRealImageTest() {
ForgeryDetectionRequest request = new ForgeryDetectionRequest();
request.setImageUrl("https://example.com/image.jpg");
BForgeryDetectionResp bResp = new BForgeryDetectionResp();
BForgeryDetectionResp.ResultDTO result = new BForgeryDetectionResp.ResultDTO();
result.setDetectionResult("real");
bResp.setResult(result);
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenReturn(ApiR.setData(bResp));
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
assertNotNull(r);
assertEquals("200", r.getCode());
assertEquals("real", r.getData().getDetectionResult());
assertNull(r.getData().getTamperedProportion());
}
@Test
public void forgeryDetectionWithHeatmapTest() {
ForgeryDetectionRequest request = new ForgeryDetectionRequest();
request.setImageBase64("base64ImageData");
request.setReturnHeatmap("true");
BForgeryDetectionResp bResp = new BForgeryDetectionResp();
BForgeryDetectionResp.ResultDTO result = new BForgeryDetectionResp.ResultDTO();
result.setDetectionResult("fake");
result.setHeatmap("heatmapBase64Data");
bResp.setResult(result);
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenReturn(ApiR.setData(bResp));
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
assertEquals("fake", r.getData().getDetectionResult());
assertEquals("heatmapBase64Data", r.getData().getHeatmap());
}
@Test
public void forgeryDetectionWithTamperedLocationTest() {
ForgeryDetectionRequest request = new ForgeryDetectionRequest();
request.setImageBase64("base64ImageData");
request.setRestrictProbability("0.5");
BForgeryDetectionResp bResp = new BForgeryDetectionResp();
BForgeryDetectionResp.ResultDTO result = new BForgeryDetectionResp.ResultDTO();
result.setDetectionResult("fake");
List<BForgeryDetectionResp.TamperedLocationDTO> locations = new ArrayList<>();
BForgeryDetectionResp.TamperedLocationDTO loc = new BForgeryDetectionResp.TamperedLocationDTO();
loc.setLeft(100);
loc.setTop(200);
loc.setWidth(300);
loc.setHeight(150);
loc.setProbability(0.95);
locations.add(loc);
result.setTamperedLocation(locations);
bResp.setResult(result);
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenReturn(ApiR.setData(bResp));
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
ForgeryDetectionResp resp = r.getData();
assertNotNull(resp.getTamperedLocation());
assertEquals(1, resp.getTamperedLocation().size());
ForgeryDetectionResp.TamperedLocation respLoc = resp.getTamperedLocation().get(0);
assertEquals(Integer.valueOf(100), respLoc.getLeft());
assertEquals(Integer.valueOf(200), respLoc.getTop());
assertEquals(Integer.valueOf(300), respLoc.getWidth());
assertEquals(Integer.valueOf(150), respLoc.getHeight());
assertEquals(Double.valueOf(0.95), respLoc.getProbability());
}
// ========== 异常流程测试 ==========
@Test
public void forgeryDetectionHandleErrorTest() {
ForgeryDetectionRequest request = new ForgeryDetectionRequest();
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenReturn(ApiR.error("imageUrl和imageBase64不能同时为空"));
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
assertNotNull(r);
assertEquals("400", r.getCode());
assertEquals("imageUrl和imageBase64不能同时为空", r.getMsg());
}
@Test
public void forgeryDetectionResultNullTest() {
ForgeryDetectionRequest request = new ForgeryDetectionRequest();
request.setImageBase64("data");
BForgeryDetectionResp bResp = new BForgeryDetectionResp();
bResp.setResult(null);
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenReturn(ApiR.setData(bResp));
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
assertNotNull(r);
assertEquals("400", r.getCode());
}
// ========== 请求映射测试 ==========
@Test
public void toBaiduRequestMappingTest() {
ForgeryDetectionRequest request = new ForgeryDetectionRequest();
request.setImageBase64("base64");
request.setImageUrl("https://example.com/img.jpg");
request.setImageUrl(TARGET_IMAGE_URL);
request.setDetectProportion("true");
request.setDetectThreshold("0.9");
request.setDetectThreshold("0.9887");
request.setReturnHeatmap("true");
request.setRestrictProbability("0.8");
BForgeryDetectionResp bResp = new BForgeryDetectionResp();
BForgeryDetectionResp.ResultDTO result = new BForgeryDetectionResp.ResultDTO();
result.setDetectionResult("real");
bResp.setResult(result);
// 2. 调用本地 /doc/forgeryDetection 接口
R<ForgeryDetectionResp> result = forgeryDetectionController.forgeryDetection(request);
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenAnswer(invocation -> {
BForgeryDetectionRequest bReq = invocation.getArgument(0);
assertEquals("base64", bReq.getImageBase64());
assertEquals("https://example.com/img.jpg", bReq.getImageUrl());
assertEquals("true", bReq.getDetectProportion());
assertEquals("0.9", bReq.getDetectThreshold());
assertEquals("true", bReq.getReturnHeatmap());
assertEquals("0.8", bReq.getRestrictProbability());
return ApiR.setData(bResp);
});
// 3. 断言
assertNotNull(result, "返回结果不能为空");
assertEquals("200", result.getCode(), "接口应返回成功");
assertNotNull(result.getData(), "返回数据不能为空");
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
assertEquals("200", r.getCode());
}
// 4. 打印接口返回值
ForgeryDetectionResp data = result.getData();
String heatmapDisplay = data.getHeatmap() != null
? data.getHeatmap().substring(0, Math.min(50, data.getHeatmap().length())) + "...(共" + data.getHeatmap().length() + "字符)"
: "null";
@Test
public void toBaiduRequestNullInputTest() {
ForgeryDetectionRequest request = null;
System.out.println("\n========== /doc/forgeryDetection 接口返回 ==========");
System.out.println("{\"code\":\"" + result.getCode() + "\",");
System.out.println(" \"msg\":\"" + result.getMsg() + "\",");
System.out.println(" \"data\":{");
System.out.println(" \"detectionResult\":\"" + data.getDetectionResult() + "\",");
System.out.println(" \"tamperedProportion\":" + data.getTamperedProportion() + ",");
System.out.println(" \"heatmap\":\"" + heatmapDisplay + "\",");
System.out.println(" \"tamperedLocation\":" + JSON.toJSONString(data.getTamperedLocation()));
System.out.println(" }");
System.out.println("}");
System.out.println("====================================================");
when(bForgeryDetectionHandle.handle(any(BForgeryDetectionRequest.class)))
.thenReturn(ApiR.error("你的image , url不能都为空"));
R<ForgeryDetectionResp> r = controller.forgeryDetection(request);
assertEquals("400", r.getCode());
// 结论
if ("fake".equals(data.getDetectionResult())) {
System.out.println(">>> 结论: 图片【已被篡改】,篡改置信度: " + data.getTamperedProportion());
} else {
System.out.println(">>> 结论: 图片【未被篡改】,篡改置信度: " + data.getTamperedProportion());
}
}
}