mirror of
https://gitee.com/zhijiantianya/ruoyi-vue-pro.git
synced 2026-03-22 05:07:17 +08:00
perf:【iot】添加 IotDeviceMessageUtils.notContainsIdentifier 方法
This commit is contained in:
@@ -38,8 +38,7 @@ public class IotDevicePropertyPostTriggerMatcher implements IotSceneRuleTriggerM
|
||||
|
||||
// 1.3 检查消息中是否包含触发器指定的属性标识符
|
||||
// 注意:属性上报可能同时上报多个属性,所以需要判断 trigger.getIdentifier() 是否在 message 的 params 中
|
||||
// TODO @puhui999:可以考虑 notXXX 方法,简化代码(尽量取反)
|
||||
if (!IotDeviceMessageUtils.containsIdentifier(message, trigger.getIdentifier())) {
|
||||
if (IotDeviceMessageUtils.notContainsIdentifier(message, trigger.getIdentifier())) {
|
||||
IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "消息中不包含属性: " +
|
||||
trigger.getIdentifier());
|
||||
return false;
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
package cn.iocoder.yudao.module.iot.service.rule.data.action.tcp;
|
||||
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.IotDataSinkTcpConfig;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link IotTcpClient} 的单元测试
|
||||
* <p>
|
||||
* 测试 dataFormat 默认值行为
|
||||
* Property 1: TCP 客户端 dataFormat 默认值行为
|
||||
* Validates: Requirements 1.1, 1.2
|
||||
*
|
||||
* @author HUIHUI
|
||||
*/
|
||||
class IotTcpClientTest {
|
||||
|
||||
@Test
|
||||
public void testConstructor_dataFormatNull() {
|
||||
// 准备参数
|
||||
String host = "localhost";
|
||||
Integer port = 8080;
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, null, null, null, null);
|
||||
|
||||
// 断言:dataFormat 为 null 时应使用默认值
|
||||
assertEquals(IotDataSinkTcpConfig.DEFAULT_DATA_FORMAT,
|
||||
ReflectUtil.getFieldValue(client, "dataFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_dataFormatEmpty() {
|
||||
// 准备参数
|
||||
String host = "localhost";
|
||||
Integer port = 8080;
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, null, null, null, "");
|
||||
|
||||
// 断言:dataFormat 为空字符串时应使用默认值
|
||||
assertEquals(IotDataSinkTcpConfig.DEFAULT_DATA_FORMAT,
|
||||
ReflectUtil.getFieldValue(client, "dataFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_dataFormatBlank() {
|
||||
// 准备参数
|
||||
String host = "localhost";
|
||||
Integer port = 8080;
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, null, null, null, " ");
|
||||
|
||||
// 断言:dataFormat 为纯空白字符串时应使用默认值
|
||||
assertEquals(IotDataSinkTcpConfig.DEFAULT_DATA_FORMAT,
|
||||
ReflectUtil.getFieldValue(client, "dataFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_dataFormatValid() {
|
||||
// 准备参数
|
||||
String host = "localhost";
|
||||
Integer port = 8080;
|
||||
String dataFormat = "BINARY";
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, null, null, null, dataFormat);
|
||||
|
||||
// 断言:dataFormat 为有效值时应保持原值
|
||||
assertEquals(dataFormat, ReflectUtil.getFieldValue(client, "dataFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_defaultValues() {
|
||||
// 准备参数
|
||||
String host = "localhost";
|
||||
Integer port = 8080;
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, null, null, null, null);
|
||||
|
||||
// 断言:验证所有默认值
|
||||
assertEquals(host, ReflectUtil.getFieldValue(client, "host"));
|
||||
assertEquals(port, ReflectUtil.getFieldValue(client, "port"));
|
||||
assertEquals(IotDataSinkTcpConfig.DEFAULT_CONNECT_TIMEOUT_MS,
|
||||
ReflectUtil.getFieldValue(client, "connectTimeoutMs"));
|
||||
assertEquals(IotDataSinkTcpConfig.DEFAULT_READ_TIMEOUT_MS,
|
||||
ReflectUtil.getFieldValue(client, "readTimeoutMs"));
|
||||
assertEquals(IotDataSinkTcpConfig.DEFAULT_SSL,
|
||||
ReflectUtil.getFieldValue(client, "ssl"));
|
||||
assertEquals(IotDataSinkTcpConfig.DEFAULT_DATA_FORMAT,
|
||||
ReflectUtil.getFieldValue(client, "dataFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConstructor_customValues() {
|
||||
// 准备参数
|
||||
String host = "192.168.1.100";
|
||||
Integer port = 9090;
|
||||
Integer connectTimeoutMs = 3000;
|
||||
Integer readTimeoutMs = 8000;
|
||||
Boolean ssl = true;
|
||||
String dataFormat = "BINARY";
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, connectTimeoutMs, readTimeoutMs, ssl, dataFormat);
|
||||
|
||||
// 断言:验证自定义值
|
||||
assertEquals(host, ReflectUtil.getFieldValue(client, "host"));
|
||||
assertEquals(port, ReflectUtil.getFieldValue(client, "port"));
|
||||
assertEquals(connectTimeoutMs, ReflectUtil.getFieldValue(client, "connectTimeoutMs"));
|
||||
assertEquals(readTimeoutMs, ReflectUtil.getFieldValue(client, "readTimeoutMs"));
|
||||
assertEquals(ssl, ReflectUtil.getFieldValue(client, "ssl"));
|
||||
assertEquals(dataFormat, ReflectUtil.getFieldValue(client, "dataFormat"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsConnected_initialState() {
|
||||
// 准备参数
|
||||
String host = "localhost";
|
||||
Integer port = 8080;
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, null, null, null, null);
|
||||
|
||||
// 断言:初始状态应为未连接
|
||||
assertFalse(client.isConnected());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testToString() {
|
||||
// 准备参数
|
||||
String host = "localhost";
|
||||
Integer port = 8080;
|
||||
|
||||
// 调用
|
||||
IotTcpClient client = new IotTcpClient(host, port, null, null, null, null);
|
||||
String result = client.toString();
|
||||
|
||||
// 断言
|
||||
assertNotNull(result);
|
||||
assertTrue(result.contains("host='localhost'"));
|
||||
assertTrue(result.contains("port=8080"));
|
||||
assertTrue(result.contains("dataFormat='JSON'"));
|
||||
assertTrue(result.contains("connected=false"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -99,6 +99,17 @@ public class IotDeviceMessageUtils {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断消息中是否不包含指定的标识符
|
||||
*
|
||||
* @param message 消息
|
||||
* @param identifier 要检查的标识符
|
||||
* @return 是否不包含
|
||||
*/
|
||||
public static boolean notContainsIdentifier(IotDeviceMessage message, String identifier) {
|
||||
return !containsIdentifier(message, identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 params 解析为 Map
|
||||
*
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
package cn.iocoder.yudao.module.iot.core.util;
|
||||
|
||||
import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
|
||||
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* {@link IotDeviceMessageUtils} 的单元测试
|
||||
@@ -138,4 +138,72 @@ public class IotDeviceMessageUtilsTest {
|
||||
Object result = IotDeviceMessageUtils.extractPropertyValue(message, "temperature");
|
||||
assertEquals(25.5, result); // 应该返回直接标识符的值
|
||||
}
|
||||
|
||||
// ========== notContainsIdentifier 测试 ==========
|
||||
|
||||
/**
|
||||
* 测试 notContainsIdentifier 与 containsIdentifier 的互补性
|
||||
* **Property 2: notContainsIdentifier 与 containsIdentifier 互补性**
|
||||
* **Validates: Requirements 4.1**
|
||||
*/
|
||||
@Test
|
||||
public void testNotContainsIdentifier_complementary_whenContains() {
|
||||
// 准备参数:消息包含指定标识符
|
||||
IotDeviceMessage message = new IotDeviceMessage();
|
||||
message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod());
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("temperature", 25);
|
||||
message.setParams(params);
|
||||
String identifier = "temperature";
|
||||
|
||||
// 调用 & 断言:验证互补性
|
||||
boolean containsResult = IotDeviceMessageUtils.containsIdentifier(message, identifier);
|
||||
boolean notContainsResult = IotDeviceMessageUtils.notContainsIdentifier(message, identifier);
|
||||
assertTrue(containsResult);
|
||||
assertFalse(notContainsResult);
|
||||
assertEquals(!containsResult, notContainsResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 notContainsIdentifier 与 containsIdentifier 的互补性
|
||||
* **Property 2: notContainsIdentifier 与 containsIdentifier 互补性**
|
||||
* **Validates: Requirements 4.1**
|
||||
*/
|
||||
@Test
|
||||
public void testNotContainsIdentifier_complementary_whenNotContains() {
|
||||
// 准备参数:消息不包含指定标识符
|
||||
IotDeviceMessage message = new IotDeviceMessage();
|
||||
message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod());
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("temperature", 25);
|
||||
message.setParams(params);
|
||||
String identifier = "humidity";
|
||||
|
||||
// 调用 & 断言:验证互补性
|
||||
boolean containsResult = IotDeviceMessageUtils.containsIdentifier(message, identifier);
|
||||
boolean notContainsResult = IotDeviceMessageUtils.notContainsIdentifier(message, identifier);
|
||||
assertFalse(containsResult);
|
||||
assertTrue(notContainsResult);
|
||||
assertEquals(!containsResult, notContainsResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试 notContainsIdentifier 与 containsIdentifier 的互补性 - 空参数场景
|
||||
* **Property 2: notContainsIdentifier 与 containsIdentifier 互补性**
|
||||
* **Validates: Requirements 4.1**
|
||||
*/
|
||||
@Test
|
||||
public void testNotContainsIdentifier_complementary_nullParams() {
|
||||
// 准备参数:params 为 null
|
||||
IotDeviceMessage message = new IotDeviceMessage();
|
||||
message.setParams(null);
|
||||
String identifier = "temperature";
|
||||
|
||||
// 调用 & 断言:验证互补性
|
||||
boolean containsResult = IotDeviceMessageUtils.containsIdentifier(message, identifier);
|
||||
boolean notContainsResult = IotDeviceMessageUtils.notContainsIdentifier(message, identifier);
|
||||
assertFalse(containsResult);
|
||||
assertTrue(notContainsResult);
|
||||
assertEquals(!containsResult, notContainsResult);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user