From 24681c81c09022f584a57006f2534b5f74723414 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期二, 30 六月 2026 09:27:31 +0800
Subject: [PATCH] 初始化项目
---
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImplTest.java | 144 +++++++++++++++++++++++++++++++----------------
1 files changed, 95 insertions(+), 49 deletions(-)
diff --git a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImplTest.java b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImplTest.java
index 8f87cb8..67be85e 100644
--- a/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImplTest.java
+++ b/yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/device/property/IotDevicePropertyServiceImplTest.java
@@ -5,11 +5,15 @@
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDeviceDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.device.IotDevicePropertyDO;
+import cn.iocoder.yudao.module.iot.dal.dataobject.product.IotProductDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.IotThingModelDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.thingmodel.model.ThingModelProperty;
import cn.iocoder.yudao.module.iot.dal.redis.device.DevicePropertyRedisDAO;
import cn.iocoder.yudao.module.iot.dal.tdengine.IotDevicePropertyMapper;
import cn.iocoder.yudao.module.iot.enums.thingmodel.IotDataSpecsDataTypeEnum;
+import cn.iocoder.yudao.module.iot.enums.thingmodel.IotThingModelTypeEnum;
+import cn.iocoder.yudao.module.iot.framework.tdengine.core.TDengineTableField;
+import cn.iocoder.yudao.module.iot.service.product.IotProductService;
import cn.iocoder.yudao.module.iot.service.thingmodel.IotThingModelService;
import org.junit.jupiter.api.Test;
import org.mockito.ArgumentCaptor;
@@ -17,8 +21,12 @@
import org.mockito.Mock;
import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
+import java.util.stream.Collectors;
import static java.util.Collections.singletonList;
import static org.junit.jupiter.api.Assertions.*;
@@ -38,6 +46,8 @@
@Mock
private IotThingModelService thingModelService;
@Mock
+ private IotProductService productService;
+ @Mock
private IotDevicePropertyMapper devicePropertyMapper;
@Mock
private DevicePropertyRedisDAO deviceDataRedisDAO;
@@ -54,6 +64,7 @@
// mock 琛屼负
when(thingModelService.getThingModelListByProductIdFromCache(device.getProductId()))
.thenReturn(singletonList(thingModel));
+ when(thingModelService.convertThingModelPropertyValue(thingModel, 100)).thenReturn(100);
// 璋冪敤
service.saveDeviceProperty(device, message);
@@ -91,64 +102,99 @@
}
@Test
- public void testSaveDeviceProperty_boolFromBooleanTrue() {
- // 鍑嗗鍙傛暟锛氱墿妯″瀷涓� BOOL锛岃澶囦笂鎶ュ師鐢� boolean true
- assertBoolValueConvertedToByte(true, (byte) 1);
- }
-
- @Test
- public void testSaveDeviceProperty_boolFromBooleanFalse() {
- // 鍑嗗鍙傛暟锛氱墿妯″瀷涓� BOOL锛岃澶囦笂鎶ュ師鐢� boolean false
- assertBoolValueConvertedToByte(false, (byte) 0);
- }
-
- @Test
- public void testSaveDeviceProperty_boolFromStringTrue() {
- // 鍑嗗鍙傛暟锛氱墿妯″瀷涓� BOOL锛岃澶囦笂鎶ュ瓧绗︿覆 "true"
- assertBoolValueConvertedToByte("true", (byte) 1);
- }
-
- @Test
- public void testSaveDeviceProperty_boolFromStringFalse() {
- // 鍑嗗鍙傛暟锛氱墿妯″瀷涓� BOOL锛岃澶囦笂鎶ュ瓧绗︿覆 "false"
- assertBoolValueConvertedToByte("false", (byte) 0);
- }
-
- @Test
- public void testSaveDeviceProperty_boolFromNumberOne() {
- // 鍑嗗鍙傛暟锛氱墿妯″瀷涓� BOOL锛岃澶囦笂鎶ユ暟瀛� 1
- assertBoolValueConvertedToByte(1, (byte) 1);
- }
-
- @Test
- public void testSaveDeviceProperty_boolFromNumberZero() {
- // 鍑嗗鍙傛暟锛氱墿妯″瀷涓� BOOL锛岃澶囦笂鎶ユ暟瀛� 0
- assertBoolValueConvertedToByte(0, (byte) 0);
- }
-
- /**
- * 鏍¢獙 BOOL 绫诲瀷灞炴�т笂鎶ュ悗锛屾渶缁堣惤鍒� properties Map 鐨勫�肩被鍨嬩笌鏁板��
- */
- private void assertBoolValueConvertedToByte(Object reportedValue, byte expected) {
- // 鍑嗗鍙傛暟
+ public void testSaveDeviceProperty_convertValueFailed() {
+ // 鍑嗗鍙傛暟锛氱墿妯″瀷瀛樺湪锛屼絾鏄睘鎬у�兼棤娉曟寜鐗╂ā鍨嬭浆鎹�
IotDeviceDO device = buildDevice();
- IotThingModelDO thingModel = buildThingModel("PowerSwitch", IotDataSpecsDataTypeEnum.BOOL.getDataType());
+ IotThingModelDO temperature = buildThingModel("Temperature", IotDataSpecsDataTypeEnum.INT.getDataType());
Map<String, Object> params = new HashMap<>();
- params.put("PowerSwitch", reportedValue);
+ params.put("Temperature", "abc");
IotDeviceMessage message = buildMessage(params);
- // mock 琛屼负
+ // mock 鏂规硶
+ when(thingModelService.getThingModelListByProductIdFromCache(device.getProductId()))
+ .thenReturn(singletonList(temperature));
+ when(thingModelService.convertThingModelPropertyValue(temperature, "abc")).thenReturn(null);
+
+ // 璋冪敤锛屽苟鏂█锛氫笉浼氭姏鍑哄紓甯�
+ assertDoesNotThrow(() -> service.saveDeviceProperty(device, message));
+
+ // 鏂█锛氭病鏈夊悎娉曞睘鎬э紝涓嶄細鍐欏叆 TDengine 涓� Redis
+ verify(devicePropertyMapper, never()).insert(any(), any(), anyLong(), anyLong());
+ verify(deviceDataRedisDAO, never()).putAll(anyLong(), any());
+ }
+
+ @Test
+ public void testSaveDeviceProperty_skipNullValue() {
+ // 鍑嗗鍙傛暟锛氬睘鎬у�间负绌猴紝涓嶈兘鍐欏叆 TDengine 涓� Redis
+ IotDeviceDO device = buildDevice();
+ IotThingModelDO thingModel = buildThingModel("Temperature", IotDataSpecsDataTypeEnum.INT.getDataType());
+ Map<String, Object> params = new HashMap<>();
+ params.put("Temperature", null);
+ IotDeviceMessage message = buildMessage(params);
+
+ // mock 鏂规硶
when(thingModelService.getThingModelListByProductIdFromCache(device.getProductId()))
.thenReturn(singletonList(thingModel));
- // 璋冪敤锛氫笉鑳芥姏寮傚父
+ // 璋冪敤锛屽苟鏂█锛氫笉浼氭姏鍑哄紓甯�
assertDoesNotThrow(() -> service.saveDeviceProperty(device, message));
- // 鏂█锛氬啓鍏ョ殑 value 鏄� byte 绫诲瀷锛屼笖鍊煎尮閰�
+ // 鏂█锛氳烦杩囩┖鍊硷紝涓嶄細杞崲灞炴�у�硷紝涔熶笉浼氬啓鍏� TDengine 涓� Redis
+ verify(thingModelService, never()).convertThingModelPropertyValue(any(), any());
+ verify(devicePropertyMapper, never()).insert(any(), any(), anyLong(), anyLong());
+ verify(deviceDataRedisDAO, never()).putAll(anyLong(), any());
+ }
+
+ @Test
+ public void testSaveDeviceProperty_skipInvalidKeyType() {
+ // 鍑嗗鍙傛暟锛歁ap 涓寘鍚潪瀛楃涓� key锛屼笉鑳藉洜涓哄己杞け璐ュ奖鍝嶅叾瀹冨悎娉曞睘鎬�
+ IotDeviceDO device = buildDevice();
+ IotThingModelDO thingModel = buildThingModel("PowerSwitch", IotDataSpecsDataTypeEnum.BOOL.getDataType());
+ Map<Object, Object> params = new HashMap<>();
+ params.put(123, 1);
+ params.put("PowerSwitch", true);
+ IotDeviceMessage message = buildMessage(params);
+
+ // mock 鏂规硶
+ when(thingModelService.getThingModelListByProductIdFromCache(device.getProductId()))
+ .thenReturn(singletonList(thingModel));
+ when(thingModelService.convertThingModelPropertyValue(thingModel, true)).thenReturn((byte) 1);
+
+ // 璋冪敤锛屽苟鏂█锛氶潪瀛楃涓� key 涓嶅奖鍝嶅叾瀹冨悎娉曞睘鎬�
+ assertDoesNotThrow(() -> service.saveDeviceProperty(device, message));
+
+ // 鏂█锛氬彧鍐欏叆鍚堟硶灞炴��
Map<String, Object> dbProperties = captureMapperInsertProperties();
- Object actual = dbProperties.get("PowerSwitch");
- assertTrue(actual instanceof Byte, "BOOL 灞炴�у簲琚浆涓� Byte 绫诲瀷锛屽疄闄呬负 " + (actual == null ? "null" : actual.getClass()));
- assertEquals(expected, actual);
+ assertEquals(1, dbProperties.size());
+ assertEquals((byte) 1, dbProperties.get("PowerSwitch"));
+ }
+
+ @Test
+ public void testDefineDevicePropertyData_fieldNameToLowerCase() {
+ // 鍑嗗鍙傛暟锛氬叏澶у啓缂╁啓鍜岄┘宄扮缉鍐欓兘闇�瑕佽浆鎹负 TDengine 瀹為檯鐨勫皬鍐欏瓧娈靛悕
+ Long productId = 2L;
+ IotProductDO product = IotProductDO.builder().id(productId).build();
+ List<IotThingModelDO> thingModels = Arrays.asList(
+ buildThingModel("Ua", IotDataSpecsDataTypeEnum.FLOAT.getDataType()),
+ buildThingModel("PfT", IotDataSpecsDataTypeEnum.FLOAT.getDataType()),
+ buildThingModel("PT", IotDataSpecsDataTypeEnum.FLOAT.getDataType()),
+ buildThingModel("PA", IotDataSpecsDataTypeEnum.FLOAT.getDataType()));
+ thingModels.forEach(thingModel -> thingModel.setType(IotThingModelTypeEnum.PROPERTY.getType()));
+
+ // mock 鏂规硶
+ when(productService.validateProductExists(productId)).thenReturn(product);
+ when(thingModelService.getThingModelListByProductId(productId)).thenReturn(thingModels);
+ when(devicePropertyMapper.getProductPropertySTableFieldList(productId)).thenReturn(Collections.emptyList());
+
+ // 璋冪敤
+ service.defineDevicePropertyData(productId);
+
+ // 鏂█锛氬瓧娈靛悕缁熶竴涓哄皬鍐欎笅鍒掔嚎锛岄伩鍏� PT 鍜屾暟鎹簱涓殑 pt 琚鍒や负涓嶅悓瀛楁
+ ArgumentCaptor<List<TDengineTableField>> captor = ArgumentCaptor.forClass(List.class);
+ verify(devicePropertyMapper).createProductPropertySTable(eq(productId), captor.capture());
+ assertEquals(Arrays.asList("ua", "pf_t", "pt", "pa"), captor.getValue().stream()
+ .map(TDengineTableField::getField)
+ .collect(Collectors.toList()));
}
// ========== 杈呭姪鏂规硶 ==========
@@ -173,7 +219,7 @@
/**
* 鏋勯�犱竴鏉″睘鎬т笂鎶ユ秷鎭�
*/
- private IotDeviceMessage buildMessage(Map<String, Object> params) {
+ private IotDeviceMessage buildMessage(Map<?, ?> params) {
IotDeviceMessage message = new IotDeviceMessage();
message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod());
message.setParams(params);
--
Gitblit v1.9.3