1、贴皮管理部分更新方法回调类型修正;2、新增exec服务单元测试配置;3增贴皮管理service、controller单元测试完善;

This commit is contained in:
gaoqr
2026-01-07 17:34:38 +08:00
parent 58c06ba5d4
commit c7476f594b
9 changed files with 774 additions and 26 deletions
@@ -104,16 +104,18 @@ public class VeneerController {
@PutMapping("")
@Operation(summary = "编辑贴皮")
public CommonResult<Boolean> updateVeneer(@Valid @RequestBody VeneerSaveReqVO reqVO) {
return success(veneerService.update(reqVO) == 1);
veneerService.update(reqVO);
return success(true);
}
@DeleteMapping("/{id}")
@Operation(summary = "删除贴皮")
public CommonResult<Boolean> deleteVeneer(@PathVariable Long id) {
return success(veneerService.delete(id) == 1);
veneerService.delete(id);
return success(true);
}
@PutMapping("/pic")
@PostMapping("/pic")
@Operation(summary = "上传贴皮照片")
@OperateLog(logArgs = false, type = CREATE)
public CommonResult<Long> uploadVeneerPic(@RequestPart(value = "file") MultipartFile file) throws IOException {
@@ -123,6 +125,7 @@ public class VeneerController {
@PostMapping("/defect")
@Operation(summary = "保存瑕疵数据")
public CommonResult<Boolean> saveDefect(@Valid @RequestBody VeneerDefectSaveReqVO reqVO) {
return success(veneerService.saveDefect(reqVO) == 1);
veneerService.saveDefect(reqVO);
return success(true);
}
}
@@ -34,7 +34,7 @@ public interface VeneerService {
* @param reqVO
* @return
*/
int update(VeneerSaveReqVO reqVO);
void update(VeneerSaveReqVO reqVO);
/**
* 删除贴皮
@@ -42,7 +42,7 @@ public interface VeneerService {
* @param id
* @return
*/
int delete(Long id);
void delete(Long id);
/**
* 上传贴皮照片
@@ -95,5 +95,5 @@ public interface VeneerService {
* @param defectSaveReqVO
* @return
*/
int saveDefect(VeneerDefectSaveReqVO defectSaveReqVO);
void saveDefect(VeneerDefectSaveReqVO defectSaveReqVO);
}
@@ -31,6 +31,7 @@ import java.time.LocalDateTime;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import static cn.hutool.core.date.DatePattern.PURE_DATETIME_PATTERN;
@@ -73,7 +74,7 @@ public class VeneerServiceImpl implements VeneerService {
}
@Override
public int update(VeneerSaveReqVO reqVO) {
public void update(VeneerSaveReqVO reqVO) {
Long id = reqVO.getId();
// 1、校验贴皮是否存在
@@ -90,18 +91,18 @@ public class VeneerServiceImpl implements VeneerService {
//3、贴皮数据入库
VeneerDO veneerDO = BeanUtil.copyProperties(reqVO, VeneerDO.class);
return veneerMapper.updateById(veneerDO);
veneerMapper.updateById(veneerDO);
}
@Override
public int delete(Long id) {
public void delete(Long id) {
// 1、校验贴皮是否存在
if (ObjectUtil.isNull(validateExist(id))) {
throw new ServiceException(VENEER_NOT_EXIST);
}
//2、删除贴皮
return veneerMapper.deleteById(id);
veneerMapper.deleteById(id);
}
@Override
@@ -161,7 +162,7 @@ public class VeneerServiceImpl implements VeneerService {
}
@Override
public int saveDefect(VeneerDefectSaveReqVO defectSaveReqVO) {
public void saveDefect(VeneerDefectSaveReqVO defectSaveReqVO) {
Long id = defectSaveReqVO.getId();
// 校验贴皮是否存在
if (ObjectUtil.isNull(validateExist(id))) {
@@ -171,12 +172,11 @@ public class VeneerServiceImpl implements VeneerService {
String defectData = defectSaveReqVO.getDefectData();
if(StringUtils.isNotEmpty(defectData)) {
// 更新瑕疵数据和状态
return veneerMapper.update(new LambdaUpdateWrapper<VeneerDO>()
veneerMapper.update(new LambdaUpdateWrapper<VeneerDO>()
.eq(VeneerDO::getId, id)
.set(VeneerDO::getDefect, true)
.set(VeneerDO::getDefectData, JsonUtils.zipString(defectData)));
}
return 1;
}
/**
@@ -209,17 +209,12 @@ public class VeneerServiceImpl implements VeneerService {
* @return
*/
public static String getFileExtension(String fileName) {
if (StringUtils.isEmpty(fileName)) {
return "";
}
int lastDotIndex = fileName.lastIndexOf('.');
if (lastDotIndex < 0 || lastDotIndex == fileName.length() - 1) {
// 没有点号,或者点号在最后一位(例如 "file."
return "";
}
// 截取后缀部分并转小写
return "." + fileName.substring(lastDotIndex + 1).toLowerCase(Locale.ROOT);
return Optional.ofNullable(fileName)
.filter(StringUtils::isNotBlank)
.filter(name -> name.contains("."))
.map(name -> name.substring(name.lastIndexOf('.')))
.filter(ext -> ext.length() > 1)
.map(ext -> ext.toLowerCase(Locale.ROOT))
.orElse(".jpg");
}
}
@@ -0,0 +1,206 @@
package com.cf.imes.module.executor.controller.admin.veneer;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.security.test.WithMockLoginUser;
import com.cf.imes.framework.test.core.ut.BaseWebUnitTest;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDefectSaveReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerSaveReqVO;
import com.cf.imes.module.executor.enums.veneer.VeneerProductLevelEnum;
import com.cf.imes.module.executor.service.veneer.VeneerService;
import com.cf.imes.module.executor.util.file.FileHelperUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletResponse;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.util.Collections;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.put;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* 贴皮管理controller 单元测试
*
* @author Gqr
* @since 2026/1/7 16:58
*/
@WebMvcTest(controllers = VeneerController.class, excludeAutoConfiguration = SecurityAutoConfiguration.class)
class VeneerControllerTest extends BaseWebUnitTest {
@Autowired
private MockMvc mockMvc;
@MockitoBean
private VeneerService veneerService;
@Autowired
private ObjectMapper objectMapper;
@Test
void getVeneerPage_success() throws Exception {
PageResult<VeneerRespVO> page = new PageResult<>();
page.setTotal(0L);
page.setList(Collections.emptyList());
when(veneerService.getPage(any())).thenReturn(page);
mockMvc.perform(get("/executor/veneer/page"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.code").value(0));
}
@Test
void exportVeneerPage_success() throws Exception {
// mock service 返回
PageResult<VeneerRespVO> page = new PageResult<>();
page.setList(Collections.emptyList());
page.setTotal(0L);
when(veneerService.getPage(any())).thenReturn(page);
mockMvc.perform(get("/executor/veneer/export"))
.andExpect(status().isOk());
}
@Test
void getVeneer_success() throws Exception {
VeneerRespVO resp = new VeneerRespVO();
resp.setId(1L);
when(veneerService.get(1L)).thenReturn(resp);
mockMvc.perform(get("/executor/veneer/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.id").value(1L));
}
@Test
void createVeneer_success() throws Exception {
// 准备参数
VeneerSaveReqVO veneerSaveReqVO = new VeneerSaveReqVO();
veneerSaveReqVO.setVeneerNo("SP14126");
veneerSaveReqVO.setClassificationName("分类名称");
veneerSaveReqVO.setProductLevel(VeneerProductLevelEnum.A.getCode());
veneerSaveReqVO.setVeneerName("贴皮名称");
veneerSaveReqVO.setNum(1);
veneerSaveReqVO.setWidth(new BigDecimal(10));
veneerSaveReqVO.setLength(new BigDecimal(20));
veneerSaveReqVO.setThickness(new BigDecimal(30));
when(veneerService.create(any())).thenReturn(1L);
mockMvc.perform(post("/executor/veneer")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(veneerSaveReqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(1L));
}
@Test
void updateVeneer_success() throws Exception {
// 准备参数
VeneerSaveReqVO veneerSaveReqVO = new VeneerSaveReqVO();
veneerSaveReqVO.setId(999l);
veneerSaveReqVO.setVeneerNo("SP14126");
veneerSaveReqVO.setClassificationName("分类名称");
veneerSaveReqVO.setProductLevel(VeneerProductLevelEnum.A.getCode());
veneerSaveReqVO.setVeneerName("贴皮名称");
veneerSaveReqVO.setNum(1);
veneerSaveReqVO.setWidth(new BigDecimal(10));
veneerSaveReqVO.setLength(new BigDecimal(20));
veneerSaveReqVO.setThickness(new BigDecimal(30));
doNothing().when(veneerService).update(any());
mockMvc.perform(put("/executor/veneer")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(veneerSaveReqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
}
@Test
void deleteVeneer_success() throws Exception {
doNothing().when(veneerService).delete(1L);
mockMvc.perform(delete("/executor/veneer/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
}
@Test
void uploadVeneerPic_success() throws Exception {
MockMultipartFile file = new MockMultipartFile(
"file", "a.jpg", "image/jpeg", "123".getBytes()
);
when(veneerService.uploadPic(any())).thenReturn(10L);
mockMvc.perform(multipart("/executor/veneer/pic")
.file(file))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(10L));
}
@Test
@WithMockLoginUser
void importExcel_success() throws Exception {
MockMultipartFile file = new MockMultipartFile(
"file", "test.xlsx",
"application/vnd.ms-excel",
new byte[]{1, 2, 3}
);
mockMvc.perform(multipart("/executor/veneer/import").file(file))
.andExpect(status().isOk());
}
@Test
void getVeneerImportTemplate_success() throws Exception {
try (MockedStatic<FileHelperUtil> mocked =
Mockito.mockStatic(FileHelperUtil.class)) {
mocked.when(() ->
FileHelperUtil.getFirstFile(
anyString(),
any(HttpServletResponse.class))
).thenAnswer(invocation -> null);
mockMvc.perform(get("/executor/veneer/import/template"))
.andExpect(status().isOk());
}
}
@Test
void saveDefect_success() throws Exception {
VeneerDefectSaveReqVO reqVO = new VeneerDefectSaveReqVO();
reqVO.setId(1L);
doNothing().when(veneerService).saveDefect(any());
mockMvc.perform(post("/executor/veneer/defect")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(reqVO)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.data").value(true));
}
}
@@ -0,0 +1,446 @@
package com.cf.imes.module.executor.service.veneer;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.pojo.CommonResult;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.json.JsonUtils;
import com.cf.imes.framework.security.test.WithMockLoginUser;
import com.cf.imes.framework.test.core.ut.BaseDbAndRedisUnitTest;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerDefectSaveReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerPageReqVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerRespVO;
import com.cf.imes.module.executor.controller.admin.veneer.vo.VeneerSaveReqVO;
import com.cf.imes.module.executor.dal.dataobject.veneer.VeneerDO;
import com.cf.imes.module.executor.dal.mysql.veneer.VeneerMapper;
import com.cf.imes.module.executor.enums.veneer.VeneerProductLevelEnum;
import com.cf.imes.module.infra.api.file.FileApi;
import com.cf.imes.module.system.api.organ.OrganApi;
import com.cf.imes.module.system.api.organ.dto.OrganizationDTO;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.Import;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import static com.cf.imes.framework.test.core.util.AssertUtils.assertServiceException;
import static com.cf.imes.framework.test.core.util.RandomUtils.randomPojo;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_NOT_EXIST;
import static com.cf.imes.module.executor.enums.ErrorCodeConstants.VENEER_NO_EXIST;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
*
*
* @author Gqr
* @since 2026/1/7 15:08
*/
@Import(VeneerServiceImpl.class)
class VeneerServiceImplTest extends BaseDbAndRedisUnitTest {
@Resource
private VeneerServiceImpl veneerService;
@MockitoBean
private FileApi fileApi;
@MockitoBean
private OrganApi organApi;
@Resource
private VeneerMapper veneerMapper;
@Test
void create_success_when_veneer_no_not_exists() {
VeneerSaveReqVO reqVO = new VeneerSaveReqVO();
reqVO.setVeneerNo("VN-001");
reqVO.setClassificationName("测试分类");
reqVO.setVeneerName("测试贴皮");
reqVO.setProductLevel(VeneerProductLevelEnum.A.getCode());
Long id = veneerService.create(reqVO);
assertNotNull(id);
VeneerDO db = veneerMapper.selectById(id);
assertEquals("VN-001", db.getVeneerNo());
}
@Test
void create_fail_when_veneer_no_exists() {
// 先插一条
VeneerDO exist = new VeneerDO();
exist.setVeneerNo("VN-002");
exist.setClassificationName("分类");
exist.setVeneerName("贴皮");
exist.setProductLevel(VeneerProductLevelEnum.A.getCode());
veneerMapper.insert(exist);
VeneerSaveReqVO reqVO = new VeneerSaveReqVO();
reqVO.setVeneerNo("VN-002");
assertServiceException(() -> veneerService.create(reqVO),
VENEER_NO_EXIST);
}
@Test
void update_success_when_same_veneer_no() {
VeneerDO exist = new VeneerDO();
exist.setVeneerNo("VN-100");
exist.setClassificationName("分类");
exist.setVeneerName("贴皮");
exist.setProductLevel(VeneerProductLevelEnum.A.getCode());
veneerMapper.insert(exist);
VeneerSaveReqVO reqVO = new VeneerSaveReqVO();
reqVO.setId(exist.getId());
reqVO.setVeneerNo("VN-100"); // 不变
reqVO.setClassificationName("新分类");
reqVO.setVeneerName("新贴皮");
reqVO.setProductLevel(VeneerProductLevelEnum.B.getCode());
assertDoesNotThrow(() -> veneerService.update(reqVO));
}
@Test
void update_fail_when_veneer_no_exists() {
VeneerDO v1 = new VeneerDO();
v1.setVeneerNo("VN-101");
v1.setClassificationName("分类1");
v1.setVeneerName("贴皮1");
v1.setProductLevel(VeneerProductLevelEnum.A.getCode());
veneerMapper.insert(v1);
VeneerDO v2 = new VeneerDO();
v2.setVeneerNo("VN-102");
v2.setClassificationName("分类2");
v2.setVeneerName("贴皮2");
v2.setProductLevel(VeneerProductLevelEnum.A.getCode());
veneerMapper.insert(v2);
VeneerSaveReqVO reqVO = new VeneerSaveReqVO();
reqVO.setId(v2.getId());
reqVO.setVeneerNo("VN-101"); // 冲突
assertServiceException(() -> veneerService.update(reqVO),
VENEER_NO_EXIST);
}
@Test
void update_fail_when_not_exists() {
VeneerSaveReqVO reqVO = new VeneerSaveReqVO();
reqVO.setId(999L);
reqVO.setVeneerNo("VN-999");
assertServiceException(() -> veneerService.update(reqVO),
VENEER_NOT_EXIST);
}
@Test
void update_fail_when_id_null(){
VeneerSaveReqVO reqVO = new VeneerSaveReqVO();
reqVO.setId(null);
assertServiceException(() -> veneerService.update(reqVO),
VENEER_NOT_EXIST);
}
@Test
void delete_success() {
VeneerDO exist = new VeneerDO();
exist.setVeneerNo("VN-200");
exist.setClassificationName("分类");
exist.setVeneerName("贴皮");
exist.setProductLevel(VeneerProductLevelEnum.A.getCode());
veneerMapper.insert(exist);
assertDoesNotThrow(() -> veneerService.delete(exist.getId()));
assertNull(veneerMapper.selectById(exist.getId()));
}
@Test
void delete_fail_when_not_exists() {
assertServiceException(() -> veneerService.delete(999L),
VENEER_NOT_EXIST);
}
@Test
@WithMockLoginUser(organId = 1L)
void uploadPic_success() throws Exception {
// mock organApi
OrganizationDTO dto = new OrganizationDTO();
dto.setName("测试组织");
when(organApi.getOrganDetails(1L))
.thenReturn(CommonResult.success(dto));
// mock fileApi
when(fileApi.createFileAndReturnId(any(byte[].class), anyString()))
.thenReturn(100L);
// mock 文件
MockMultipartFile file = new MockMultipartFile(
"file",
"test.png",
"image/png",
"test-content".getBytes()
);
Long fileId = veneerService.uploadPic(file);
assertEquals(100L, fileId);
// 验证 fileApi 调用
verify(fileApi).createFileAndReturnId(
any(byte[].class),
argThat(name -> name.contains("测试组织-veneer-pic-file-"))
);
}
@Test
@WithMockLoginUser(organId = 1L)
void uploadPic_fail_when_organ_api_error() {
when(organApi.getOrganDetails(1L))
.thenReturn(CommonResult.error(500, "组织服务异常"));
MockMultipartFile file = new MockMultipartFile(
"file",
"test.jpg",
"image/jpeg",
"content".getBytes()
);
ServiceException ex = assertThrows(
ServiceException.class,
() -> veneerService.uploadPic(file)
);
assertEquals(500, ex.getCode());
assertEquals("组织服务异常", ex.getMessage());
verify(fileApi, never()).createFileAndReturnId(any(), any());
}
@Test
void getPage_success_when_has_data() {
VeneerDO exist = new VeneerDO();
exist.setVeneerNo("VN-200");
exist.setClassificationName("分类");
exist.setVeneerName("贴皮名称");
exist.setProductLevel(VeneerProductLevelEnum.A.getCode());
exist.setRemark("备注");
exist.setWidth(new BigDecimal(10));
exist.setThickness(new BigDecimal(9));
veneerMapper.insert(exist);
VeneerPageReqVO pageReqVO = new VeneerPageReqVO();
pageReqVO.setVeneerNo("VN-200");
pageReqVO.setClassificationName("分类");
pageReqVO.setVeneerName("贴皮名称");
pageReqVO.setProductLevel(VeneerProductLevelEnum.A.getCode());
pageReqVO.setWidth(new BigDecimal[]{new BigDecimal(0), new BigDecimal(20)});
pageReqVO.setThickness(new BigDecimal[]{new BigDecimal(5)});
pageReqVO.setRemark("");
PageResult<VeneerRespVO> result =
veneerService.getPage(pageReqVO);
assertEquals(1L, result.getTotal());
assertEquals(1, result.getList().size());
assertEquals("VN-200", result.getList().get(0).getVeneerNo());
}
@Test
void getPage_empty(){
VeneerPageReqVO reqVO = new VeneerPageReqVO();
PageResult<VeneerRespVO> result = veneerService.getPage(reqVO);
assertNotNull(result);
assertEquals(0L, result.getTotal());
}
@Test
void get_success_with_defect_data() {
String json = "{\"a\":1}";
String zipped = JsonUtils.zipString(json);
VeneerDO veneer = new VeneerDO();
veneer.setVeneerNo("VN-301");
veneer.setClassificationName("分类");
veneer.setVeneerName("贴皮");
veneer.setProductLevel(1);
veneer.setDefectData(zipped);
veneer.setOrganId(1L);
veneerMapper.insert(veneer);
VeneerRespVO respVO = veneerService.get(veneer.getId());
assertNotNull(respVO);
assertEquals("VN-301", respVO.getVeneerNo());
assertEquals(json, respVO.getDefectData()); // 已解压
}
@Test
void get_success_without_defect_data() {
VeneerDO veneer = new VeneerDO();
veneer.setVeneerNo("VN-302");
veneer.setClassificationName("分类");
veneer.setVeneerName("贴皮");
veneer.setProductLevel(1);
veneer.setOrganId(1L);
veneerMapper.insert(veneer);
VeneerRespVO respVO = veneerService.get(veneer.getId());
assertNotNull(respVO);
assertNull(respVO.getDefectData());
}
@Test
void get_fail_when_not_exist() {
assertServiceException(() -> veneerService.get(999L),
VENEER_NOT_EXIST);
}
@Test
void getOrgVeneerNo_empty() {
Map<String, Long> map = veneerService.getOrgVeneerNo();
assertNotNull(map);
assertTrue(map.isEmpty());
}
@Test
void getOrgVeneerNo_success() {
VeneerDO v1 = new VeneerDO();
v1.setVeneerNo("VN-401");
v1.setClassificationName("分类");
v1.setVeneerName("贴皮");
v1.setProductLevel(VeneerProductLevelEnum.A.getCode());
v1.setOrganId(1L);
VeneerDO v2 = new VeneerDO();
v2.setVeneerNo("VN-402");
v2.setClassificationName("分类");
v2.setVeneerName("贴皮");
v2.setProductLevel(VeneerProductLevelEnum.C.getCode());
v2.setOrganId(1L);
veneerMapper.insert(v1);
veneerMapper.insert(v2);
Map<String, Long> map = veneerService.getOrgVeneerNo();
assertEquals(2, map.size());
assertEquals(v1.getId(), map.get("VN-401"));
assertEquals(v2.getId(), map.get("VN-402"));
}
@Test
void batch_success() {
VeneerDO v1 = randomPojo(VeneerDO.class, o -> {
o.setProductLevel(VeneerProductLevelEnum.A.getCode());
});
VeneerDO v2 = randomPojo(VeneerDO.class, o -> {
o.setProductLevel(VeneerProductLevelEnum.A.getCode());
});
List<VeneerDO> list = List.of(
v1, v2
);
veneerService.batchInsert(list);
// 验证数据真的进库了
List<VeneerDO> dbList = veneerMapper.selectList();
assertEquals(2, dbList.size());
v1.setVeneerName("更新后贴皮名称1");
v2.setVeneerName("更新后贴皮名称2");
veneerService.batchUpdate(List.of(v1, v2));
VeneerDO db1 = veneerMapper.selectById(v1.getId());
VeneerDO db2 = veneerMapper.selectById(v2.getId());
assertEquals("更新后贴皮名称1", db1.getVeneerName());
assertEquals("更新后贴皮名称2", db2.getVeneerName());
}
@Test
void saveDefect_success_whenDefectDataNotEmpty() {
String defectJson = "{\"x\":10,\"y\":20}";
// 先插入贴皮
VeneerDO veneer = randomPojo(VeneerDO.class, o -> {
o.setProductLevel(VeneerProductLevelEnum.A.getCode());
o.setDefectData(defectJson);
});
veneerMapper.insert(veneer);
VeneerDefectSaveReqVO req = new VeneerDefectSaveReqVO();
req.setId(veneer.getId());
req.setDefectData(defectJson);
assertDoesNotThrow(() -> veneerService.saveDefect(req));
// 再查数据库
VeneerDO db = veneerMapper.selectById(veneer.getId());
assertTrue(db.getDefect());
assertNotNull(db.getDefectData());
assertEquals(defectJson, JsonUtils.unzipString(db.getDefectData()));
}
@Test
void saveDefect_throwException_whenVeneerNotExist() {
VeneerDefectSaveReqVO req = new VeneerDefectSaveReqVO();
req.setId(99999L);
assertServiceException(() -> veneerService.saveDefect(req),
VENEER_NOT_EXIST);
}
@Test
void saveDefect_doNothing_whenDefectDataEmpty() {
// 先插入贴皮
VeneerDO veneer = randomPojo(VeneerDO.class, o -> {
o.setProductLevel(VeneerProductLevelEnum.A.getCode());
o.setDefectData(null);
o.setDefect(false);
});
veneerMapper.insert(veneer);
VeneerDefectSaveReqVO req = new VeneerDefectSaveReqVO();
req.setId(veneer.getId());
req.setDefectData("");
assertDoesNotThrow(() -> veneerService.saveDefect(req));
VeneerDO db = veneerMapper.selectById(veneer.getId());
assertFalse(db.getDefect());
assertNull(db.getDefectData());
}
@Test
void getFileExtension_whenEmpty() {
assertEquals(".jpg", veneerService.getFileExtension("file."));
}
}
@@ -0,0 +1,59 @@
spring:
main:
lazy-initialization: true # 开启懒加载,加快速度
banner-mode: off # 单元测试,禁用 Banner
--- #################### 数据库相关配置 ####################
spring:
# 数据源配置项
datasource:
name: ruoyi-vue-pro
url: jdbc:h2:mem:testdb;MODE=MYSQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=value; # MODE 使用 MySQL 模式;DATABASE_TO_UPPER 配置表和字段使用小写
driver-class-name: org.h2.Driver
username: sa
password:
druid:
async-init: true # 单元测试,异步初始化 Druid 连接池,提升启动速度
initial-size: 1 # 单元测试,配置为 1,提升启动速度
sql:
init:
schema-locations: classpath:/sql/create_tables.sql
# Redis 配置。Redisson 默认的配置足够使用,一般不需要进行调优
redis:
host: 127.0.0.1 # 地址
port: 16379 # 端口(单元测试,使用 16379 端口)
database: 0 # 数据库索引
mybatis:
lazy-initialization: true # 单元测试,设置 MyBatis Mapper 延迟加载,加速每个单元测试
mybatis-plus:
global-config:
db-config:
id-type: AUTO # H2 主键递增
--- #################### 定时任务相关配置 ####################
--- #################### 配置中心相关配置 ####################
--- #################### 服务保障相关配置 ####################
# Lock4j 配置项(单元测试,禁用 Lock4j)
# Resilience4j 配置项
--- #################### 监控相关配置 ####################
--- #################### 晨丰相关配置 ####################
# 晨丰配置项,设置当前项目所有自定义的配置
chenfeng:
info:
base-package: com.cf.imes.module
captcha:
timeout: 5m
width: 160
height: 60
enable: true
@@ -0,0 +1,4 @@
<configuration>
<!-- 引用 Spring Boot 的 logback 基础配置 -->
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
</configuration>
@@ -0,0 +1 @@
DELETE FROM "veneers";
@@ -0,0 +1,34 @@
CREATE TABLE IF NOT EXISTS "veneers"
(
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
"veneer_no" varchar(32) NOT NULL,
"source_veneer_no" varchar(32) DEFAULT NULL,
"batch_no" varchar(32) DEFAULT NULL,
"organ_id" bigint NOT NULL DEFAULT 1,
"classification_name" varchar(64) NOT NULL,
"veneer_name" varchar(64) NOT NULL,
"product_level" tinyint NOT NULL,
"brand" varchar(64) DEFAULT NULL,
"spec" varchar(64) DEFAULT NULL,
"material" varchar(64) DEFAULT NULL,
"color" varchar(32) DEFAULT NULL,
"factory" varchar(128) DEFAULT NULL,
"num" int DEFAULT NULL,
"defect" bit NOT NULL DEFAULT FALSE,
"defect_data" clob DEFAULT NULL,
"remain" bit NOT NULL DEFAULT FALSE,
"source_plan_no" bigint DEFAULT NULL,
"plan_no" bigint DEFAULT NULL,
"status" tinyint NOT NULL DEFAULT 0,
"width" decimal(8, 3) NOT NULL DEFAULT 0.000,
"length" decimal(8, 3) NOT NULL DEFAULT 0.000,
"thickness" decimal(8, 3) NOT NULL DEFAULT 0.000,
"remark" varchar(255) DEFAULT NULL,
"file_id" bigint DEFAULT NULL,
"creator" varchar(64) DEFAULT NULL,
"create_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updater" varchar(64) DEFAULT NULL,
"update_time" timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
"deleted" bit NOT NULL DEFAULT FALSE,
PRIMARY KEY ("id")
) COMMENT '贴皮表 veneers_{N}';