Commit 21945e6b1e381e0138bf553dfe75384beac89d7c

Authored by 芋道源码
Committed by Gitee
2 parents 439b68e3 2b3e2d6d

!1413 场景联动优化 review 提到的逻辑

Merge pull request !1413 from puhui999/feature/iot
Showing 21 changed files with 1203 additions and 1002 deletions
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/enums/rule/IotSceneRuleConditionTypeEnum.java
1 1 package cn.iocoder.yudao.module.iot.enums.rule;
2 2  
  3 +import cn.hutool.core.util.ArrayUtil;
3 4 import cn.iocoder.yudao.framework.common.core.ArrayValuable;
4 5 import lombok.Getter;
5 6 import lombok.RequiredArgsConstructor;
... ... @@ -32,4 +33,8 @@ public enum IotSceneRuleConditionTypeEnum implements ArrayValuable<Integer> {
32 33 return ARRAYS;
33 34 }
34 35  
  36 + public static IotSceneRuleConditionTypeEnum typeOf(Integer type) {
  37 + return ArrayUtil.firstMatch(item -> item.getType().equals(type), values());
  38 + }
  39 +
35 40 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/IotSceneRuleServiceImpl.java
... ... @@ -55,9 +55,8 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
55 55 @Resource
56 56 private IotDeviceService deviceService;
57 57  
58   - // TODO @puhui999:sceneRuleMatcherManager 变量名
59 58 @Resource
60   - private IotSceneRuleMatcherManager matcherManager;
  59 + private IotSceneRuleMatcherManager sceneRuleMatcherManager;
61 60 @Resource
62 61 private List<IotSceneRuleAction> sceneRuleActions;
63 62  
... ... @@ -275,7 +274,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
275 274 private boolean matchSingleTrigger(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger, IotSceneRuleDO sceneRule) {
276 275 try {
277 276 // 2. 检查触发器的条件分组
278   - return matcherManager.isMatched(message, trigger) && isTriggerConditionGroupsMatched(message, trigger, sceneRule);
  277 + return sceneRuleMatcherManager.isMatched(message, trigger) && isTriggerConditionGroupsMatched(message, trigger, sceneRule);
279 278 } catch (Exception e) {
280 279 log.error("[matchSingleTrigger][触发器匹配异常] sceneRuleId: {}, triggerType: {}, message: {}",
281 280 sceneRule.getId(), trigger.getType(), message, e);
... ... @@ -334,7 +333,7 @@ public class IotSceneRuleServiceImpl implements IotSceneRuleService {
334 333 private boolean isTriggerConditionMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition,
335 334 IotSceneRuleDO sceneRule, IotSceneRuleDO.Trigger trigger) {
336 335 try {
337   - return matcherManager.isConditionMatched(message, condition);
  336 + return sceneRuleMatcherManager.isConditionMatched(message, condition);
338 337 } catch (Exception e) {
339 338 log.error("[isTriggerConditionMatched][规则场景编号({}) 的触发器({}) 条件匹配异常]",
340 339 sceneRule.getId(), trigger, e);
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/IotSceneRuleMatcherManager.java
... ... @@ -12,7 +12,6 @@ import org.springframework.stereotype.Component;
12 12  
13 13 import java.util.*;
14 14 import java.util.function.Function;
15   -import java.util.stream.Collectors;
16 15  
17 16 import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
18 17  
... ... @@ -37,33 +36,26 @@ public class IotSceneRuleMatcherManager {
37 36 */
38 37 private final Map<IotSceneRuleConditionTypeEnum, IotSceneRuleConditionMatcher> conditionMatchers;
39 38  
40   - /**
41   - * 所有匹配器列表(按优先级排序)
42   - */
43   - // TODO @puhui999:貌似 local variable 也可以
44   - private final List<IotSceneRuleMatcher> allMatchers;
45   -
46 39 public IotSceneRuleMatcherManager(List<IotSceneRuleMatcher> matchers) {
47 40 if (CollUtil.isEmpty(matchers)) {
48 41 log.warn("[IotSceneRuleMatcherManager][没有找到任何匹配器]");
49 42 this.triggerMatchers = new HashMap<>();
50 43 this.conditionMatchers = new HashMap<>();
51   - this.allMatchers = new ArrayList<>();
52 44 return;
53 45 }
54 46  
55 47 // 按优先级排序并过滤启用的匹配器
56   - this.allMatchers = matchers.stream()
  48 + List<IotSceneRuleMatcher> allMatchers = matchers.stream()
57 49 .filter(IotSceneRuleMatcher::isEnabled)
58 50 .sorted(Comparator.comparing(IotSceneRuleMatcher::getPriority))
59   - .collect(Collectors.toList());
  51 + .toList();
60 52  
61 53 // 分离触发器匹配器和条件匹配器
62   - List<IotSceneRuleTriggerMatcher> triggerMatchers = this.allMatchers.stream()
  54 + List<IotSceneRuleTriggerMatcher> triggerMatchers = allMatchers.stream()
63 55 .filter(matcher -> matcher instanceof IotSceneRuleTriggerMatcher)
64 56 .map(matcher -> (IotSceneRuleTriggerMatcher) matcher)
65 57 .toList();
66   - List<IotSceneRuleConditionMatcher> conditionMatchers = this.allMatchers.stream()
  58 + List<IotSceneRuleConditionMatcher> conditionMatchers = allMatchers.stream()
67 59 .filter(matcher -> matcher instanceof IotSceneRuleConditionMatcher)
68 60 .map(matcher -> (IotSceneRuleConditionMatcher) matcher)
69 61 .toList();
... ... @@ -92,7 +84,7 @@ public class IotSceneRuleMatcherManager {
92 84  
93 85 // 日志输出初始化信息
94 86 log.info("[IotSceneRuleMatcherManager][初始化完成,共加载({})个匹配器,其中触发器匹配器({})个,条件匹配器({})个]",
95   - this.allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size());
  87 + allMatchers.size(), this.triggerMatchers.size(), this.conditionMatchers.size());
96 88 this.triggerMatchers.forEach((type, matcher) ->
97 89 log.info("[IotSceneRuleMatcherManager][触发器匹配器类型: ({}), 优先级: ({})] ", type, matcher.getPriority()));
98 90 this.conditionMatchers.forEach((type, matcher) ->
... ... @@ -123,7 +115,7 @@ public class IotSceneRuleMatcherManager {
123 115 }
124 116  
125 117 try {
126   - return matcher.isMatched(message, trigger);
  118 + return matcher.matches(message, trigger);
127 119 } catch (Exception e) {
128 120 log.error("[isMatched][触发器匹配异常] message: {}, trigger: {}", message, trigger, e);
129 121 return false;
... ... @@ -144,7 +136,7 @@ public class IotSceneRuleMatcherManager {
144 136 }
145 137  
146 138 // 根据条件类型查找对应的匹配器
147   - IotSceneRuleConditionTypeEnum conditionType = findConditionTypeEnum(condition.getType());
  139 + IotSceneRuleConditionTypeEnum conditionType = IotSceneRuleConditionTypeEnum.typeOf(condition.getType());
148 140 if (conditionType == null) {
149 141 log.warn("[isConditionMatched][conditionType({}) 未知的条件类型]", condition.getType());
150 142 return false;
... ... @@ -157,45 +149,11 @@ public class IotSceneRuleMatcherManager {
157 149  
158 150 // 执行匹配逻辑
159 151 try {
160   - return matcher.isMatched(message, condition);
  152 + return matcher.matches(message, condition);
161 153 } catch (Exception e) {
162 154 log.error("[isConditionMatched][message({}) condition({}) 条件匹配异常]", message, condition, e);
163 155 return false;
164 156 }
165 157 }
166 158  
167   - /**
168   - * 根据类型值查找条件类型枚举
169   - *
170   - * @param typeValue 类型值
171   - * @return 条件类型枚举
172   - */
173   - private IotSceneRuleConditionTypeEnum findConditionTypeEnum(Integer typeValue) {
174   - // TODO @puhui999:是不是搞到枚举类里?
175   - return Arrays.stream(IotSceneRuleConditionTypeEnum.values())
176   - .filter(type -> type.getType().equals(typeValue))
177   - .findFirst()
178   - .orElse(null);
179   - }
180   -
181   - // TODO @puhui999:下面两个方法,是不是也可以删除哈?
182   -
183   - /**
184   - * 获取所有支持的触发器类型
185   - *
186   - * @return 支持的触发器类型列表
187   - */
188   - public Set<IotSceneRuleTriggerTypeEnum> getSupportedTriggerTypes() {
189   - return new HashSet<>(triggerMatchers.keySet());
190   - }
191   -
192   - /**
193   - * 获取所有支持的条件类型
194   - *
195   - * @return 支持的条件类型列表
196   - */
197   - public Set<IotSceneRuleConditionTypeEnum> getSupportedConditionTypes() {
198   - return new HashSet<>(conditionMatchers.keySet());
199   - }
200   -
201 159 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/CurrentTimeConditionMatcher.java
... ... @@ -43,7 +43,7 @@ public class CurrentTimeConditionMatcher implements IotSceneRuleConditionMatcher
43 43 }
44 44  
45 45 @Override
46   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
  46 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
47 47 // 1.1 基础参数校验
48 48 if (!IotSceneRuleMatcherHelper.isBasicConditionValid(condition)) {
49 49 IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "条件基础参数无效");
... ... @@ -123,7 +123,6 @@ public class CurrentTimeConditionMatcher implements IotSceneRuleConditionMatcher
123 123 isDateTimeOperator(operatorEnum);
124 124 }
125 125  
126   - // TODO @puhui999:switch 兼容下 jdk8
127 126 /**
128 127 * 匹配日期时间(时间戳)
129 128 * 直接实现时间戳比较逻辑
... ... @@ -131,15 +130,17 @@ public class CurrentTimeConditionMatcher implements IotSceneRuleConditionMatcher
131 130 private boolean matchDateTime(long currentTimestamp, IotSceneRuleConditionOperatorEnum operatorEnum, String param) {
132 131 try {
133 132 long targetTimestamp = Long.parseLong(param);
134   - return switch (operatorEnum) {
135   - case DATE_TIME_GREATER_THAN -> currentTimestamp > targetTimestamp;
136   - case DATE_TIME_LESS_THAN -> currentTimestamp < targetTimestamp;
137   - case DATE_TIME_BETWEEN -> matchDateTimeBetween(currentTimestamp, param);
138   - default -> {
  133 + switch (operatorEnum) {
  134 + case DATE_TIME_GREATER_THAN:
  135 + return currentTimestamp > targetTimestamp;
  136 + case DATE_TIME_LESS_THAN:
  137 + return currentTimestamp < targetTimestamp;
  138 + case DATE_TIME_BETWEEN:
  139 + return matchDateTimeBetween(currentTimestamp, param);
  140 + default:
139 141 log.warn("[matchDateTime][operatorEnum({}) 不支持的日期时间操作符]", operatorEnum);
140   - yield false;
141   - }
142   - };
  142 + return false;
  143 + }
143 144 } catch (Exception e) {
144 145 log.error("[matchDateTime][operatorEnum({}) param({}) 日期时间匹配异常]", operatorEnum, param, e);
145 146 return false;
... ... @@ -167,15 +168,17 @@ public class CurrentTimeConditionMatcher implements IotSceneRuleConditionMatcher
167 168 private boolean matchTime(LocalTime currentTime, IotSceneRuleConditionOperatorEnum operatorEnum, String param) {
168 169 try {
169 170 LocalTime targetTime = parseTime(param);
170   - return switch (operatorEnum) {
171   - case TIME_GREATER_THAN -> currentTime.isAfter(targetTime);
172   - case TIME_LESS_THAN -> currentTime.isBefore(targetTime);
173   - case TIME_BETWEEN -> matchTimeBetween(currentTime, param);
174   - default -> {
  171 + switch (operatorEnum) {
  172 + case TIME_GREATER_THAN:
  173 + return currentTime.isAfter(targetTime);
  174 + case TIME_LESS_THAN:
  175 + return currentTime.isBefore(targetTime);
  176 + case TIME_BETWEEN:
  177 + return matchTimeBetween(currentTime, param);
  178 + default:
175 179 log.warn("[matchTime][operatorEnum({}) 不支持的时间操作符]", operatorEnum);
176   - yield false;
177   - }
178   - };
  180 + return false;
  181 + }
179 182 } catch (Exception e) {
180 183 log.error("[matchTime][][operatorEnum({}) param({}) 时间解析异常]", operatorEnum, param, e);
181 184 return false;
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DevicePropertyConditionMatcher.java
... ... @@ -22,9 +22,8 @@ public class DevicePropertyConditionMatcher implements IotSceneRuleConditionMatc
22 22 return IotSceneRuleConditionTypeEnum.DEVICE_PROPERTY;
23 23 }
24 24  
25   - // TODO @puhui999:matches 会不会更好?参考的 org.hamcrest.Matcher jdk 接口
26 25 @Override
27   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
  26 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
28 27 // 1.1 基础参数校验
29 28 if (!IotSceneRuleMatcherHelper.isBasicConditionValid(condition)) {
30 29 IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "条件基础参数无效");
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DeviceStateConditionMatcher.java
... ... @@ -22,7 +22,7 @@ public class DeviceStateConditionMatcher implements IotSceneRuleConditionMatcher
22 22 }
23 23  
24 24 @Override
25   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
  25 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition) {
26 26 // 1.1 基础参数校验
27 27 if (!IotSceneRuleMatcherHelper.isBasicConditionValid(condition)) {
28 28 IotSceneRuleMatcherHelper.logConditionMatchFailure(message, condition, "条件基础参数无效");
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/IotSceneRuleConditionMatcher.java
... ... @@ -33,6 +33,6 @@ public interface IotSceneRuleConditionMatcher extends IotSceneRuleMatcher {
33 33 * @param condition 触发条件
34 34 * @return 是否匹配
35 35 */
36   - boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition);
  36 + boolean matches(IotDeviceMessage message, IotSceneRuleDO.TriggerCondition condition);
37 37  
38 38 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcher.java
... ... @@ -25,7 +25,7 @@ public class DeviceEventPostTriggerMatcher implements IotSceneRuleTriggerMatcher
25 25 }
26 26  
27 27 @Override
28   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
  28 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
29 29 // 1.1 基础参数校验
30 30 if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
31 31 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcher.java
... ... @@ -24,7 +24,7 @@ public class DevicePropertyPostTriggerMatcher implements IotSceneRuleTriggerMatc
24 24 }
25 25  
26 26 @Override
27   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
  27 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
28 28 // 1.1 基础参数校验
29 29 if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
30 30 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcher.java
... ... @@ -24,7 +24,7 @@ public class DeviceServiceInvokeTriggerMatcher implements IotSceneRuleTriggerMat
24 24 }
25 25  
26 26 @Override
27   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
  27 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
28 28 // 1.1 基础参数校验
29 29 if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
30 30 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcher.java
... ... @@ -23,7 +23,7 @@ public class DeviceStateUpdateTriggerMatcher implements IotSceneRuleTriggerMatch
23 23 }
24 24  
25 25 @Override
26   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
  26 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
27 27 // 1.1 基础参数校验
28 28 if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
29 29 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/IotSceneRuleTriggerMatcher.java
... ... @@ -33,6 +33,6 @@ public interface IotSceneRuleTriggerMatcher extends IotSceneRuleMatcher {
33 33 * @param trigger 触发器配置
34 34 * @return 是否匹配
35 35 */
36   - boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger);
  36 + boolean matches(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger);
37 37  
38 38 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/main/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcher.java
... ... @@ -25,7 +25,7 @@ public class TimerTriggerMatcher implements IotSceneRuleTriggerMatcher {
25 25 }
26 26  
27 27 @Override
28   - public boolean isMatched(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
  28 + public boolean matches(IotDeviceMessage message, IotSceneRuleDO.Trigger trigger) {
29 29 // 1.1 基础参数校验
30 30 if (!IotSceneRuleMatcherHelper.isBasicTriggerValid(trigger)) {
31 31 IotSceneRuleMatcherHelper.logTriggerMatchFailure(message, trigger, "触发器基础参数无效");
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/CurrentTimeConditionMatcherTest.java
... ... @@ -5,103 +5,110 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
6 6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum;
7 7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
8   -import org.junit.jupiter.api.BeforeEach;
9 8 import org.junit.jupiter.api.Test;
  9 +import org.mockito.InjectMocks;
10 10  
11 11 import java.time.LocalDateTime;
12 12 import java.time.ZoneOffset;
13 13  
  14 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  15 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
14 16 import static org.junit.jupiter.api.Assertions.*;
15 17  
16 18 /**
17   - * {@link CurrentTimeConditionMatcher} 的单元测试类
  19 + * {@link CurrentTimeConditionMatcher} 的单元测试
18 20 *
19 21 * @author HUIHUI
20 22 */
21 23 public class CurrentTimeConditionMatcherTest extends BaseMockitoUnitTest {
22 24  
  25 + @InjectMocks
23 26 private CurrentTimeConditionMatcher matcher;
24 27  
25   - @BeforeEach
26   - public void setUp() {
27   - matcher = new CurrentTimeConditionMatcher();
28   - }
29   -
30 28 @Test
31 29 public void testGetSupportedConditionType() {
32   - // when & then
33   - assertEquals(IotSceneRuleConditionTypeEnum.CURRENT_TIME, matcher.getSupportedConditionType());
  30 + // 调用
  31 + IotSceneRuleConditionTypeEnum result = matcher.getSupportedConditionType();
  32 +
  33 + // 断言
  34 + assertEquals(IotSceneRuleConditionTypeEnum.CURRENT_TIME, result);
34 35 }
35 36  
36 37 @Test
37 38 public void testGetPriority() {
38   - // when & then
39   - assertEquals(40, matcher.getPriority());
  39 + // 调用
  40 + int result = matcher.getPriority();
  41 +
  42 + // 断言
  43 + assertEquals(40, result);
40 44 }
41 45  
42 46 @Test
43 47 public void testIsEnabled() {
44   - // when & then
45   - assertTrue(matcher.isEnabled());
  48 + // 调用
  49 + boolean result = matcher.isEnabled();
  50 +
  51 + // 断言
  52 + assertTrue(result);
46 53 }
47 54  
48 55 // ========== 时间戳条件测试 ==========
49 56  
50 57 @Test
51   - public void testIsMatched_DateTimeGreaterThan_Success() {
52   - // given
53   - IotDeviceMessage message = new IotDeviceMessage();
  58 + public void testMatches_DateTimeGreaterThan_success() {
  59 + // 准备参数
  60 + IotDeviceMessage message = createDeviceMessage();
54 61 long pastTimestamp = LocalDateTime.now().minusHours(1).toEpochSecond(ZoneOffset.of("+8"));
55 62 IotSceneRuleDO.TriggerCondition condition = createDateTimeCondition(
56 63 IotSceneRuleConditionOperatorEnum.DATE_TIME_GREATER_THAN.getOperator(),
57 64 String.valueOf(pastTimestamp)
58 65 );
59 66  
60   - // when
61   - boolean result = matcher.isMatched(message, condition);
  67 + // 调用
  68 + boolean result = matcher.matches(message, condition);
62 69  
63   - // then
  70 + // 断言
64 71 assertTrue(result);
65 72 }
66 73  
67 74 @Test
68   - public void testIsMatched_DateTimeGreaterThan_Failure() {
69   - // given
70   - IotDeviceMessage message = new IotDeviceMessage();
  75 + public void testMatches_DateTimeGreaterThan_fail() {
  76 + // 准备参数
  77 + IotDeviceMessage message = createDeviceMessage();
71 78 long futureTimestamp = LocalDateTime.now().plusHours(1).toEpochSecond(ZoneOffset.of("+8"));
72 79 IotSceneRuleDO.TriggerCondition condition = createDateTimeCondition(
73 80 IotSceneRuleConditionOperatorEnum.DATE_TIME_GREATER_THAN.getOperator(),
74 81 String.valueOf(futureTimestamp)
75 82 );
76 83  
77   - // when
78   - boolean result = matcher.isMatched(message, condition);
  84 + // 调用
  85 + boolean result = matcher.matches(message, condition);
79 86  
80   - // then
  87 + // 断言
81 88 assertFalse(result);
82 89 }
83 90  
84 91 @Test
85   - public void testIsMatched_DateTimeLessThan_Success() {
86   - // given
87   - IotDeviceMessage message = new IotDeviceMessage();
  92 + public void testMatches_DateTimeLessThan_success() {
  93 + // 准备参数
  94 + IotDeviceMessage message = createDeviceMessage();
88 95 long futureTimestamp = LocalDateTime.now().plusHours(1).toEpochSecond(ZoneOffset.of("+8"));
89 96 IotSceneRuleDO.TriggerCondition condition = createDateTimeCondition(
90 97 IotSceneRuleConditionOperatorEnum.DATE_TIME_LESS_THAN.getOperator(),
91 98 String.valueOf(futureTimestamp)
92 99 );
93 100  
94   - // when
95   - boolean result = matcher.isMatched(message, condition);
  101 + // 调用
  102 + boolean result = matcher.matches(message, condition);
96 103  
97   - // then
  104 + // 断言
98 105 assertTrue(result);
99 106 }
100 107  
101 108 @Test
102   - public void testIsMatched_DateTimeBetween_Success() {
103   - // given
104   - IotDeviceMessage message = new IotDeviceMessage();
  109 + public void testMatches_DateTimeBetween_success() {
  110 + // 准备参数
  111 + IotDeviceMessage message = createDeviceMessage();
105 112 long startTimestamp = LocalDateTime.now().minusHours(1).toEpochSecond(ZoneOffset.of("+8"));
106 113 long endTimestamp = LocalDateTime.now().plusHours(1).toEpochSecond(ZoneOffset.of("+8"));
107 114 IotSceneRuleDO.TriggerCondition condition = createDateTimeCondition(
... ... @@ -109,17 +116,17 @@ public class CurrentTimeConditionMatcherTest extends BaseMockitoUnitTest {
109 116 startTimestamp + "," + endTimestamp
110 117 );
111 118  
112   - // when
113   - boolean result = matcher.isMatched(message, condition);
  119 + // 调用
  120 + boolean result = matcher.matches(message, condition);
114 121  
115   - // then
  122 + // 断言
116 123 assertTrue(result);
117 124 }
118 125  
119 126 @Test
120   - public void testIsMatched_DateTimeBetween_Failure() {
121   - // given
122   - IotDeviceMessage message = new IotDeviceMessage();
  127 + public void testMatches_DateTimeBetween_fail() {
  128 + // 准备参数
  129 + IotDeviceMessage message = createDeviceMessage();
123 130 long startTimestamp = LocalDateTime.now().plusHours(1).toEpochSecond(ZoneOffset.of("+8"));
124 131 long endTimestamp = LocalDateTime.now().plusHours(2).toEpochSecond(ZoneOffset.of("+8"));
125 132 IotSceneRuleDO.TriggerCondition condition = createDateTimeCondition(
... ... @@ -127,78 +134,78 @@ public class CurrentTimeConditionMatcherTest extends BaseMockitoUnitTest {
127 134 startTimestamp + "," + endTimestamp
128 135 );
129 136  
130   - // when
131   - boolean result = matcher.isMatched(message, condition);
  137 + // 调用
  138 + boolean result = matcher.matches(message, condition);
132 139  
133   - // then
  140 + // 断言
134 141 assertFalse(result);
135 142 }
136 143  
137 144 // ========== 当日时间条件测试 ==========
138 145  
139 146 @Test
140   - public void testIsMatched_TimeGreaterThan_EarlyMorning() {
141   - // given
142   - IotDeviceMessage message = new IotDeviceMessage();
  147 + public void testMatches_TimeGreaterThan_earlyMorning() {
  148 + // 准备参数
  149 + IotDeviceMessage message = createDeviceMessage();
143 150 IotSceneRuleDO.TriggerCondition condition = createTimeCondition(
144 151 IotSceneRuleConditionOperatorEnum.TIME_GREATER_THAN.getOperator(),
145 152 "06:00:00" // 早上6点
146 153 );
147 154  
148   - // when
149   - boolean result = matcher.isMatched(message, condition);
  155 + // 调用
  156 + boolean result = matcher.matches(message, condition);
150 157  
151   - // then
  158 + // 断言
152 159 // 结果取决于当前时间,如果当前时间大于6点则为true
153 160 assertNotNull(result);
154 161 }
155 162  
156 163 @Test
157   - public void testIsMatched_TimeLessThan_LateNight() {
158   - // given
159   - IotDeviceMessage message = new IotDeviceMessage();
  164 + public void testMatches_TimeLessThan_lateNight() {
  165 + // 准备参数
  166 + IotDeviceMessage message = createDeviceMessage();
160 167 IotSceneRuleDO.TriggerCondition condition = createTimeCondition(
161 168 IotSceneRuleConditionOperatorEnum.TIME_LESS_THAN.getOperator(),
162 169 "23:59:59" // 晚上11点59分59秒
163 170 );
164 171  
165   - // when
166   - boolean result = matcher.isMatched(message, condition);
  172 + // 调用
  173 + boolean result = matcher.matches(message, condition);
167 174  
168   - // then
  175 + // 断言
169 176 // 大部分情况下应该为true,除非在午夜前1秒运行测试
170 177 assertNotNull(result);
171 178 }
172 179  
173 180 @Test
174   - public void testIsMatched_TimeBetween_AllDay() {
175   - // given
176   - IotDeviceMessage message = new IotDeviceMessage();
  181 + public void testMatches_TimeBetween_allDay() {
  182 + // 准备参数
  183 + IotDeviceMessage message = createDeviceMessage();
177 184 IotSceneRuleDO.TriggerCondition condition = createTimeCondition(
178 185 IotSceneRuleConditionOperatorEnum.TIME_BETWEEN.getOperator(),
179 186 "00:00:00,23:59:59" // 全天
180 187 );
181 188  
182   - // when
183   - boolean result = matcher.isMatched(message, condition);
  189 + // 调用
  190 + boolean result = matcher.matches(message, condition);
184 191  
185   - // then
  192 + // 断言
186 193 assertTrue(result); // 全天范围应该总是匹配
187 194 }
188 195  
189 196 @Test
190   - public void testIsMatched_TimeBetween_WorkingHours() {
191   - // given
192   - IotDeviceMessage message = new IotDeviceMessage();
  197 + public void testMatches_TimeBetween_workingHours() {
  198 + // 准备参数
  199 + IotDeviceMessage message = createDeviceMessage();
193 200 IotSceneRuleDO.TriggerCondition condition = createTimeCondition(
194 201 IotSceneRuleConditionOperatorEnum.TIME_BETWEEN.getOperator(),
195 202 "09:00:00,17:00:00" // 工作时间
196 203 );
197 204  
198   - // when
199   - boolean result = matcher.isMatched(message, condition);
  205 + // 调用
  206 + boolean result = matcher.matches(message, condition);
200 207  
201   - // then
  208 + // 断言
202 209 // 结果取决于当前时间是否在工作时间内
203 210 assertNotNull(result);
204 211 }
... ... @@ -206,98 +213,107 @@ public class CurrentTimeConditionMatcherTest extends BaseMockitoUnitTest {
206 213 // ========== 异常情况测试 ==========
207 214  
208 215 @Test
209   - public void testIsMatched_NullCondition() {
210   - // given
211   - IotDeviceMessage message = new IotDeviceMessage();
  216 + public void testMatches_nullCondition() {
  217 + // 准备参数
  218 + IotDeviceMessage message = createDeviceMessage();
212 219  
213   - // when
214   - boolean result = matcher.isMatched(message, null);
  220 + // 调用
  221 + boolean result = matcher.matches(message, null);
215 222  
216   - // then
  223 + // 断言
217 224 assertFalse(result);
218 225 }
219 226  
220 227 @Test
221   - public void testIsMatched_NullConditionType() {
222   - // given
223   - IotDeviceMessage message = new IotDeviceMessage();
  228 + public void testMatches_nullConditionType() {
  229 + // 准备参数
  230 + IotDeviceMessage message = createDeviceMessage();
224 231 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
225 232 condition.setType(null);
226 233  
227   - // when
228   - boolean result = matcher.isMatched(message, condition);
  234 + // 调用
  235 + boolean result = matcher.matches(message, condition);
229 236  
230   - // then
  237 + // 断言
231 238 assertFalse(result);
232 239 }
233 240  
234 241 @Test
235   - public void testIsMatched_InvalidOperator() {
236   - // given
237   - IotDeviceMessage message = new IotDeviceMessage();
  242 + public void testMatches_invalidOperator() {
  243 + // 准备参数
  244 + IotDeviceMessage message = createDeviceMessage();
238 245 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
239 246 condition.setType(IotSceneRuleConditionTypeEnum.CURRENT_TIME.getType());
240   - condition.setOperator("invalid_operator");
  247 + condition.setOperator(randomString()); // 随机无效操作符
241 248 condition.setParam("12:00:00");
242 249  
243   - // when
244   - boolean result = matcher.isMatched(message, condition);
  250 + // 调用
  251 + boolean result = matcher.matches(message, condition);
245 252  
246   - // then
  253 + // 断言
247 254 assertFalse(result);
248 255 }
249 256  
250 257 @Test
251   - public void testIsMatched_InvalidTimeFormat() {
252   - // given
253   - IotDeviceMessage message = new IotDeviceMessage();
  258 + public void testMatches_invalidTimeFormat() {
  259 + // 准备参数
  260 + IotDeviceMessage message = createDeviceMessage();
254 261 IotSceneRuleDO.TriggerCondition condition = createTimeCondition(
255 262 IotSceneRuleConditionOperatorEnum.TIME_GREATER_THAN.getOperator(),
256   - "invalid-time-format"
  263 + randomString() // 随机无效时间格式
257 264 );
258 265  
259   - // when
260   - boolean result = matcher.isMatched(message, condition);
  266 + // 调用
  267 + boolean result = matcher.matches(message, condition);
261 268  
262   - // then
  269 + // 断言
263 270 assertFalse(result);
264 271 }
265 272  
266 273 @Test
267   - public void testIsMatched_InvalidTimestampFormat() {
268   - // given
269   - IotDeviceMessage message = new IotDeviceMessage();
  274 + public void testMatches_invalidTimestampFormat() {
  275 + // 准备参数
  276 + IotDeviceMessage message = createDeviceMessage();
270 277 IotSceneRuleDO.TriggerCondition condition = createDateTimeCondition(
271 278 IotSceneRuleConditionOperatorEnum.DATE_TIME_GREATER_THAN.getOperator(),
272   - "invalid-timestamp"
  279 + randomString() // 随机无效时间戳格式
273 280 );
274 281  
275   - // when
276   - boolean result = matcher.isMatched(message, condition);
  282 + // 调用
  283 + boolean result = matcher.matches(message, condition);
277 284  
278   - // then
  285 + // 断言
279 286 assertFalse(result);
280 287 }
281 288  
282 289 @Test
283   - public void testIsMatched_InvalidBetweenFormat() {
284   - // given
285   - IotDeviceMessage message = new IotDeviceMessage();
  290 + public void testMatches_invalidBetweenFormat() {
  291 + // 准备参数
  292 + IotDeviceMessage message = createDeviceMessage();
286 293 IotSceneRuleDO.TriggerCondition condition = createTimeCondition(
287 294 IotSceneRuleConditionOperatorEnum.TIME_BETWEEN.getOperator(),
288 295 "09:00:00" // 缺少结束时间
289 296 );
290 297  
291   - // when
292   - boolean result = matcher.isMatched(message, condition);
  298 + // 调用
  299 + boolean result = matcher.matches(message, condition);
293 300  
294   - // then
  301 + // 断言
295 302 assertFalse(result);
296 303 }
297 304  
298 305 // ========== 辅助方法 ==========
299 306  
300 307 /**
  308 + * 创建设备消息
  309 + */
  310 + private IotDeviceMessage createDeviceMessage() {
  311 + IotDeviceMessage message = new IotDeviceMessage();
  312 + message.setDeviceId(randomLongId());
  313 + return message;
  314 + }
  315 +
  316 + /**
301 317 * 创建日期时间条件
302 318 */
303 319 private IotSceneRuleDO.TriggerCondition createDateTimeCondition(String operator, String param) {
... ... @@ -318,4 +334,5 @@ public class CurrentTimeConditionMatcherTest extends BaseMockitoUnitTest {
318 334 condition.setParam(param);
319 335 return condition;
320 336 }
  337 +
321 338 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DevicePropertyConditionMatcherTest.java
... ... @@ -6,185 +6,206 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
6 6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
7 7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum;
8 8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
9   -import org.junit.jupiter.api.BeforeEach;
10 9 import org.junit.jupiter.api.Test;
  10 +import org.mockito.InjectMocks;
11 11  
12 12 import java.util.HashMap;
13 13 import java.util.Map;
14 14  
  15 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  16 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
15 17 import static org.junit.jupiter.api.Assertions.*;
16 18  
17 19 /**
18   - * {@link DevicePropertyConditionMatcher} 的单元测试类
  20 + * {@link DevicePropertyConditionMatcher} 的单元测试
19 21 *
20 22 * @author HUIHUI
21 23 */
22 24 public class DevicePropertyConditionMatcherTest extends BaseMockitoUnitTest {
23 25  
  26 + @InjectMocks
24 27 private DevicePropertyConditionMatcher matcher;
25 28  
26   - @BeforeEach
27   - public void setUp() {
28   - matcher = new DevicePropertyConditionMatcher();
29   - }
30   -
31 29 @Test
32 30 public void testGetSupportedConditionType() {
33   - // when & then
34   - assertEquals(IotSceneRuleConditionTypeEnum.DEVICE_PROPERTY, matcher.getSupportedConditionType());
  31 + // 调用
  32 + IotSceneRuleConditionTypeEnum result = matcher.getSupportedConditionType();
  33 +
  34 + // 断言
  35 + assertEquals(IotSceneRuleConditionTypeEnum.DEVICE_PROPERTY, result);
35 36 }
36 37  
37 38 @Test
38 39 public void testGetPriority() {
39   - // when & then
40   - assertEquals(20, matcher.getPriority());
  40 + // 调用
  41 + int result = matcher.getPriority();
  42 +
  43 + // 断言
  44 + assertEquals(20, result);
41 45 }
42 46  
43 47 @Test
44 48 public void testIsEnabled() {
45   - // when & then
46   - assertTrue(matcher.isEnabled());
  49 + // 调用
  50 + boolean result = matcher.isEnabled();
  51 +
  52 + // 断言
  53 + assertTrue(result);
47 54 }
48 55  
49 56 @Test
50   - public void testIsMatched_Success_TemperatureEquals() {
51   - // given
52   - Map<String, Object> properties = MapUtil.of("temperature", 25.5);
  57 + public void testMatches_temperatureEquals_success() {
  58 + // 准备参数
  59 + String propertyName = "temperature";
  60 + Double propertyValue = 25.5;
  61 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
53 62 IotDeviceMessage message = createDeviceMessage(properties);
54 63 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
55   - "temperature",
  64 + propertyName,
56 65 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
57   - "25.5"
  66 + String.valueOf(propertyValue)
58 67 );
59 68  
60   - // when
61   - boolean result = matcher.isMatched(message, condition);
  69 + // 调用
  70 + boolean result = matcher.matches(message, condition);
62 71  
63   - // then
  72 + // 断言
64 73 assertTrue(result);
65 74 }
66 75  
67 76 @Test
68   - public void testIsMatched_Success_HumidityGreaterThan() {
69   - // given
70   - Map<String, Object> properties = MapUtil.of("humidity", 75);
  77 + public void testMatches_humidityGreaterThan_success() {
  78 + // 准备参数
  79 + String propertyName = "humidity";
  80 + Integer propertyValue = 75;
  81 + Integer compareValue = 70;
  82 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
71 83 IotDeviceMessage message = createDeviceMessage(properties);
72 84 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
73   - "humidity",
  85 + propertyName,
74 86 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
75   - "70"
  87 + String.valueOf(compareValue)
76 88 );
77 89  
78   - // when
79   - boolean result = matcher.isMatched(message, condition);
  90 + // 调用
  91 + boolean result = matcher.matches(message, condition);
80 92  
81   - // then
  93 + // 断言
82 94 assertTrue(result);
83 95 }
84 96  
85 97 @Test
86   - public void testIsMatched_Success_PressureLessThan() {
87   - // given
88   - Map<String, Object> properties = MapUtil.of("pressure", 1010.5);
  98 + public void testMatches_pressureLessThan_success() {
  99 + // 准备参数
  100 + String propertyName = "pressure";
  101 + Double propertyValue = 1010.5;
  102 + Integer compareValue = 1020;
  103 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
89 104 IotDeviceMessage message = createDeviceMessage(properties);
90 105 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
91   - "pressure",
  106 + propertyName,
92 107 IotSceneRuleConditionOperatorEnum.LESS_THAN.getOperator(),
93   - "1020"
  108 + String.valueOf(compareValue)
94 109 );
95 110  
96   - // when
97   - boolean result = matcher.isMatched(message, condition);
  111 + // 调用
  112 + boolean result = matcher.matches(message, condition);
98 113  
99   - // then
  114 + // 断言
100 115 assertTrue(result);
101 116 }
102 117  
103 118 @Test
104   - public void testIsMatched_Success_StatusNotEquals() {
105   - // given
106   - Map<String, Object> properties = MapUtil.of("status", "active");
  119 + public void testMatches_statusNotEquals_success() {
  120 + // 准备参数
  121 + String propertyName = "status";
  122 + String propertyValue = "active";
  123 + String compareValue = "inactive";
  124 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
107 125 IotDeviceMessage message = createDeviceMessage(properties);
108 126 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
109   - "status",
  127 + propertyName,
110 128 IotSceneRuleConditionOperatorEnum.NOT_EQUALS.getOperator(),
111   - "inactive"
  129 + compareValue
112 130 );
113 131  
114   - // when
115   - boolean result = matcher.isMatched(message, condition);
  132 + // 调用
  133 + boolean result = matcher.matches(message, condition);
116 134  
117   - // then
  135 + // 断言
118 136 assertTrue(result);
119 137 }
120 138  
121 139 @Test
122   - public void testIsMatched_Failure_PropertyMismatch() {
123   - // given
124   - Map<String, Object> properties = MapUtil.of("temperature", 15.0);
  140 + public void testMatches_propertyMismatch_fail() {
  141 + // 准备参数
  142 + String propertyName = "temperature";
  143 + Double propertyValue = 15.0;
  144 + Integer compareValue = 20;
  145 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
125 146 IotDeviceMessage message = createDeviceMessage(properties);
126 147 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
127   - "temperature",
  148 + propertyName,
128 149 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
129   - "20"
  150 + String.valueOf(compareValue)
130 151 );
131 152  
132   - // when
133   - boolean result = matcher.isMatched(message, condition);
  153 + // 调用
  154 + boolean result = matcher.matches(message, condition);
134 155  
135   - // then
  156 + // 断言
136 157 assertFalse(result);
137 158 }
138 159  
139 160 @Test
140   - public void testIsMatched_Failure_PropertyNotFound() {
141   - // given
  161 + public void testMatches_propertyNotFound_fail() {
  162 + // 准备参数
142 163 Map<String, Object> properties = MapUtil.of("temperature", 25.5);
143 164 IotDeviceMessage message = createDeviceMessage(properties);
144 165 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
145   - "humidity", // 不存在的属性
  166 + randomString(), // 随机不存在的属性名
146 167 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
147 168 "50"
148 169 );
149 170  
150   - // when
151   - boolean result = matcher.isMatched(message, condition);
  171 + // 调用
  172 + boolean result = matcher.matches(message, condition);
152 173  
153   - // then
  174 + // 断言
154 175 assertFalse(result);
155 176 }
156 177  
157 178 @Test
158   - public void testIsMatched_Failure_NullCondition() {
159   - // given
  179 + public void testMatches_nullCondition_fail() {
  180 + // 准备参数
160 181 Map<String, Object> properties = MapUtil.of("temperature", 25.5);
161 182 IotDeviceMessage message = createDeviceMessage(properties);
162 183  
163   - // when
164   - boolean result = matcher.isMatched(message, null);
  184 + // 调用
  185 + boolean result = matcher.matches(message, null);
165 186  
166   - // then
  187 + // 断言
167 188 assertFalse(result);
168 189 }
169 190  
170 191 @Test
171   - public void testIsMatched_Failure_NullConditionType() {
172   - // given
  192 + public void testMatches_nullConditionType_fail() {
  193 + // 准备参数
173 194 Map<String, Object> properties = MapUtil.of("temperature", 25.5);
174 195 IotDeviceMessage message = createDeviceMessage(properties);
175 196 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
176 197 condition.setType(null);
177 198  
178   - // when
179   - boolean result = matcher.isMatched(message, condition);
  199 + // 调用
  200 + boolean result = matcher.matches(message, condition);
180 201  
181   - // then
  202 + // 断言
182 203 assertFalse(result);
183 204 }
184 205  
185 206 @Test
186   - public void testIsMatched_Failure_MissingIdentifier() {
187   - // given
  207 + public void testMatches_missingIdentifier_fail() {
  208 + // 准备参数
188 209 Map<String, Object> properties = MapUtil.of("temperature", 25.5);
189 210 IotDeviceMessage message = createDeviceMessage(properties);
190 211 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
... ... @@ -193,16 +214,16 @@ public class DevicePropertyConditionMatcherTest extends BaseMockitoUnitTest {
193 214 condition.setOperator(IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator());
194 215 condition.setParam("20");
195 216  
196   - // when
197   - boolean result = matcher.isMatched(message, condition);
  217 + // 调用
  218 + boolean result = matcher.matches(message, condition);
198 219  
199   - // then
  220 + // 断言
200 221 assertFalse(result);
201 222 }
202 223  
203 224 @Test
204   - public void testIsMatched_Failure_MissingOperator() {
205   - // given
  225 + public void testMatches_missingOperator_fail() {
  226 + // 准备参数
206 227 Map<String, Object> properties = MapUtil.of("temperature", 25.5);
207 228 IotDeviceMessage message = createDeviceMessage(properties);
208 229 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
... ... @@ -211,16 +232,16 @@ public class DevicePropertyConditionMatcherTest extends BaseMockitoUnitTest {
211 232 condition.setOperator(null); // 缺少操作符
212 233 condition.setParam("20");
213 234  
214   - // when
215   - boolean result = matcher.isMatched(message, condition);
  235 + // 调用
  236 + boolean result = matcher.matches(message, condition);
216 237  
217   - // then
  238 + // 断言
218 239 assertFalse(result);
219 240 }
220 241  
221 242 @Test
222   - public void testIsMatched_Failure_MissingParam() {
223   - // given
  243 + public void testMatches_missingParam_fail() {
  244 + // 准备参数
224 245 Map<String, Object> properties = MapUtil.of("temperature", 25.5);
225 246 IotDeviceMessage message = createDeviceMessage(properties);
226 247 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
... ... @@ -229,123 +250,131 @@ public class DevicePropertyConditionMatcherTest extends BaseMockitoUnitTest {
229 250 condition.setOperator(IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator());
230 251 condition.setParam(null); // 缺少参数
231 252  
232   - // when
233   - boolean result = matcher.isMatched(message, condition);
  253 + // 调用
  254 + boolean result = matcher.matches(message, condition);
234 255  
235   - // then
  256 + // 断言
236 257 assertFalse(result);
237 258 }
238 259  
239 260 @Test
240   - public void testIsMatched_Failure_NullMessage() {
241   - // given
  261 + public void testMatches_nullMessage_fail() {
  262 + // 准备参数
242 263 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
243 264 "temperature",
244 265 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
245 266 "20"
246 267 );
247 268  
248   - // when
249   - boolean result = matcher.isMatched(null, condition);
  269 + // 调用
  270 + boolean result = matcher.matches(null, condition);
250 271  
251   - // then
  272 + // 断言
252 273 assertFalse(result);
253 274 }
254 275  
255 276 @Test
256   - public void testIsMatched_Failure_NullDeviceProperties() {
257   - // given
  277 + public void testMatches_nullDeviceProperties_fail() {
  278 + // 准备参数
258 279 IotDeviceMessage message = new IotDeviceMessage();
259 280 message.setParams(null);
260   -
261 281 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
262 282 "temperature",
263 283 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
264 284 "20"
265 285 );
266 286  
267   - // when
268   - boolean result = matcher.isMatched(message, condition);
  287 + // 调用
  288 + boolean result = matcher.matches(message, condition);
269 289  
270   - // then
  290 + // 断言
271 291 assertFalse(result);
272 292 }
273 293  
274 294 @Test
275   - public void testIsMatched_Success_GreaterThanOrEquals() {
276   - // given
277   - Map<String, Object> properties = MapUtil.of("voltage", 12.0);
  295 + public void testMatches_voltageGreaterThanOrEquals_success() {
  296 + // 准备参数
  297 + String propertyName = "voltage";
  298 + Double propertyValue = 12.0;
  299 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
278 300 IotDeviceMessage message = createDeviceMessage(properties);
279 301 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
280   - "voltage",
  302 + propertyName,
281 303 IotSceneRuleConditionOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator(),
282   - "12.0"
  304 + String.valueOf(propertyValue)
283 305 );
284 306  
285   - // when
286   - boolean result = matcher.isMatched(message, condition);
  307 + // 调用
  308 + boolean result = matcher.matches(message, condition);
287 309  
288   - // then
  310 + // 断言
289 311 assertTrue(result);
290 312 }
291 313  
292 314 @Test
293   - public void testIsMatched_Success_LessThanOrEquals() {
294   - // given
295   - Map<String, Object> properties = MapUtil.of("current", 2.5);
  315 + public void testMatches_currentLessThanOrEquals_success() {
  316 + // 准备参数
  317 + String propertyName = "current";
  318 + Double propertyValue = 2.5;
  319 + Double compareValue = 3.0;
  320 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
296 321 IotDeviceMessage message = createDeviceMessage(properties);
297 322 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
298   - "current",
  323 + propertyName,
299 324 IotSceneRuleConditionOperatorEnum.LESS_THAN_OR_EQUALS.getOperator(),
300   - "3.0"
  325 + String.valueOf(compareValue)
301 326 );
302 327  
303   - // when
304   - boolean result = matcher.isMatched(message, condition);
  328 + // 调用
  329 + boolean result = matcher.matches(message, condition);
305 330  
306   - // then
  331 + // 断言
307 332 assertTrue(result);
308 333 }
309 334  
310 335 @Test
311   - public void testIsMatched_Success_StringProperty() {
312   - // given
313   - Map<String, Object> properties = MapUtil.of("mode", "auto");
  336 + public void testMatches_stringProperty_success() {
  337 + // 准备参数
  338 + String propertyName = "mode";
  339 + String propertyValue = "auto";
  340 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
314 341 IotDeviceMessage message = createDeviceMessage(properties);
315 342 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
316   - "mode",
  343 + propertyName,
317 344 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
318   - "auto"
  345 + propertyValue
319 346 );
320 347  
321   - // when
322   - boolean result = matcher.isMatched(message, condition);
  348 + // 调用
  349 + boolean result = matcher.matches(message, condition);
323 350  
324   - // then
  351 + // 断言
325 352 assertTrue(result);
326 353 }
327 354  
328 355 @Test
329   - public void testIsMatched_Success_BooleanProperty() {
330   - // given
331   - Map<String, Object> properties = MapUtil.of("enabled", true);
  356 + public void testMatches_booleanProperty_success() {
  357 + // 准备参数
  358 + String propertyName = "enabled";
  359 + Boolean propertyValue = true;
  360 + Map<String, Object> properties = MapUtil.of(propertyName, propertyValue);
332 361 IotDeviceMessage message = createDeviceMessage(properties);
333 362 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
334   - "enabled",
  363 + propertyName,
335 364 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
336   - "true"
  365 + String.valueOf(propertyValue)
337 366 );
338 367  
339   - // when
340   - boolean result = matcher.isMatched(message, condition);
  368 + // 调用
  369 + boolean result = matcher.matches(message, condition);
341 370  
342   - // then
  371 + // 断言
343 372 assertTrue(result);
344 373 }
345 374  
346 375 @Test
347   - public void testIsMatched_Success_MultipleProperties() {
348   - // given
  376 + public void testMatches_multipleProperties_success() {
  377 + // 准备参数
349 378 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
350 379 .put("temperature", 25.5)
351 380 .put("humidity", 60)
... ... @@ -353,16 +382,18 @@ public class DevicePropertyConditionMatcherTest extends BaseMockitoUnitTest {
353 382 .put("enabled", true)
354 383 .build();
355 384 IotDeviceMessage message = createDeviceMessage(properties);
  385 + String targetProperty = "humidity";
  386 + Integer targetValue = 60;
356 387 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
357   - "humidity",
  388 + targetProperty,
358 389 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
359   - "60"
  390 + String.valueOf(targetValue)
360 391 );
361 392  
362   - // when
363   - boolean result = matcher.isMatched(message, condition);
  393 + // 调用
  394 + boolean result = matcher.matches(message, condition);
364 395  
365   - // then
  396 + // 断言
366 397 assertTrue(result);
367 398 }
368 399  
... ... @@ -373,6 +404,7 @@ public class DevicePropertyConditionMatcherTest extends BaseMockitoUnitTest {
373 404 */
374 405 private IotDeviceMessage createDeviceMessage(Map<String, Object> properties) {
375 406 IotDeviceMessage message = new IotDeviceMessage();
  407 + message.setDeviceId(randomLongId());
376 408 message.setParams(properties);
377 409 return message;
378 410 }
... ... @@ -388,4 +420,5 @@ public class DevicePropertyConditionMatcherTest extends BaseMockitoUnitTest {
388 420 condition.setParam(param);
389 421 return condition;
390 422 }
  423 +
391 424 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/condition/DeviceStateConditionMatcherTest.java
... ... @@ -6,307 +6,327 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
6 6 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
7 7 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum;
8 8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionTypeEnum;
9   -import org.junit.jupiter.api.BeforeEach;
10 9 import org.junit.jupiter.api.Test;
  10 +import org.mockito.InjectMocks;
11 11  
  12 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  13 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
12 14 import static org.junit.jupiter.api.Assertions.*;
13 15  
14 16 /**
15   - * {@link DeviceStateConditionMatcher} 的单元测试类
  17 + * {@link DeviceStateConditionMatcher} 的单元测试
16 18 *
17 19 * @author HUIHUI
18 20 */
19 21 public class DeviceStateConditionMatcherTest extends BaseMockitoUnitTest {
20 22  
  23 + @InjectMocks
21 24 private DeviceStateConditionMatcher matcher;
22 25  
23   - @BeforeEach
24   - public void setUp() {
25   - matcher = new DeviceStateConditionMatcher();
26   - }
27   -
28 26 @Test
29 27 public void testGetSupportedConditionType() {
30   - // when & then
31   - assertEquals(IotSceneRuleConditionTypeEnum.DEVICE_STATE, matcher.getSupportedConditionType());
  28 + // 调用
  29 + IotSceneRuleConditionTypeEnum result = matcher.getSupportedConditionType();
  30 +
  31 + // 断言
  32 + assertEquals(IotSceneRuleConditionTypeEnum.DEVICE_STATE, result);
32 33 }
33 34  
34 35 @Test
35 36 public void testGetPriority() {
36   - // when & then
37   - assertEquals(30, matcher.getPriority());
  37 + // 调用
  38 + int result = matcher.getPriority();
  39 +
  40 + // 断言
  41 + assertEquals(30, result);
38 42 }
39 43  
40 44 @Test
41 45 public void testIsEnabled() {
42   - // when & then
43   - assertTrue(matcher.isEnabled());
  46 + // 调用
  47 + boolean result = matcher.isEnabled();
  48 +
  49 + // 断言
  50 + assertTrue(result);
44 51 }
45 52  
46 53 @Test
47   - public void testIsMatched_Success_OnlineState() {
48   - // given
49   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
  54 + public void testMatches_onlineState_success() {
  55 + // 准备参数
  56 + IotDeviceStateEnum deviceState = IotDeviceStateEnum.ONLINE;
  57 + IotDeviceMessage message = createDeviceMessage(deviceState.getState());
50 58 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
51 59 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
52   - IotDeviceStateEnum.ONLINE.getState().toString()
  60 + deviceState.getState().toString()
53 61 );
54 62  
55   - // when
56   - boolean result = matcher.isMatched(message, condition);
  63 + // 调用
  64 + boolean result = matcher.matches(message, condition);
57 65  
58   - // then
  66 + // 断言
59 67 assertTrue(result);
60 68 }
61 69  
62 70 @Test
63   - public void testIsMatched_Success_OfflineState() {
64   - // given
65   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.OFFLINE.getState());
  71 + public void testMatches_offlineState_success() {
  72 + // 准备参数
  73 + IotDeviceStateEnum deviceState = IotDeviceStateEnum.OFFLINE;
  74 + IotDeviceMessage message = createDeviceMessage(deviceState.getState());
66 75 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
67 76 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
68   - IotDeviceStateEnum.OFFLINE.getState().toString()
  77 + deviceState.getState().toString()
69 78 );
70 79  
71   - // when
72   - boolean result = matcher.isMatched(message, condition);
  80 + // 调用
  81 + boolean result = matcher.matches(message, condition);
73 82  
74   - // then
  83 + // 断言
75 84 assertTrue(result);
76 85 }
77 86  
78 87 @Test
79   - public void testIsMatched_Success_InactiveState() {
80   - // given
81   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.INACTIVE.getState());
  88 + public void testMatches_inactiveState_success() {
  89 + // 准备参数
  90 + IotDeviceStateEnum deviceState = IotDeviceStateEnum.INACTIVE;
  91 + IotDeviceMessage message = createDeviceMessage(deviceState.getState());
82 92 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
83 93 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
84   - IotDeviceStateEnum.INACTIVE.getState().toString()
  94 + deviceState.getState().toString()
85 95 );
86 96  
87   - // when
88   - boolean result = matcher.isMatched(message, condition);
  97 + // 调用
  98 + boolean result = matcher.matches(message, condition);
89 99  
90   - // then
  100 + // 断言
91 101 assertTrue(result);
92 102 }
93 103  
94 104 @Test
95   - public void testIsMatched_Failure_StateMismatch() {
96   - // given
97   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
  105 + public void testMatches_stateMismatch_fail() {
  106 + // 准备参数
  107 + IotDeviceStateEnum actualState = IotDeviceStateEnum.ONLINE;
  108 + IotDeviceStateEnum expectedState = IotDeviceStateEnum.OFFLINE;
  109 + IotDeviceMessage message = createDeviceMessage(actualState.getState());
98 110 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
99 111 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
100   - IotDeviceStateEnum.OFFLINE.getState().toString()
  112 + expectedState.getState().toString()
101 113 );
102 114  
103   - // when
104   - boolean result = matcher.isMatched(message, condition);
  115 + // 调用
  116 + boolean result = matcher.matches(message, condition);
105 117  
106   - // then
  118 + // 断言
107 119 assertFalse(result);
108 120 }
109 121  
110 122 @Test
111   - public void testIsMatched_Success_NotEqualsOperator() {
112   - // given
113   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
  123 + public void testMatches_notEqualsOperator_success() {
  124 + // 准备参数
  125 + IotDeviceStateEnum actualState = IotDeviceStateEnum.ONLINE;
  126 + IotDeviceStateEnum compareState = IotDeviceStateEnum.OFFLINE;
  127 + IotDeviceMessage message = createDeviceMessage(actualState.getState());
114 128 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
115 129 IotSceneRuleConditionOperatorEnum.NOT_EQUALS.getOperator(),
116   - IotDeviceStateEnum.OFFLINE.getState().toString()
  130 + compareState.getState().toString()
117 131 );
118 132  
119   - // when
120   - boolean result = matcher.isMatched(message, condition);
  133 + // 调用
  134 + boolean result = matcher.matches(message, condition);
121 135  
122   - // then
  136 + // 断言
123 137 assertTrue(result);
124 138 }
125 139  
126 140 @Test
127   - public void testIsMatched_Success_GreaterThanOperator() {
128   - // given
129   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.OFFLINE.getState()); // 2
  141 + public void testMatches_greaterThanOperator_success() {
  142 + // 准备参数
  143 + IotDeviceStateEnum actualState = IotDeviceStateEnum.OFFLINE; // 状态值为 2
  144 + IotDeviceStateEnum compareState = IotDeviceStateEnum.ONLINE; // 状态值为 1
  145 + IotDeviceMessage message = createDeviceMessage(actualState.getState());
130 146 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
131 147 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
132   - IotDeviceStateEnum.ONLINE.getState().toString() // 1
  148 + compareState.getState().toString()
133 149 );
134 150  
135   - // when
136   - boolean result = matcher.isMatched(message, condition);
  151 + // 调用
  152 + boolean result = matcher.matches(message, condition);
137 153  
138   - // then
  154 + // 断言
139 155 assertTrue(result);
140 156 }
141 157  
142 158 @Test
143   - public void testIsMatched_Success_LessThanOperator() {
144   - // given
145   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.INACTIVE.getState()); // 0
  159 + public void testMatches_lessThanOperator_success() {
  160 + // 准备参数
  161 + IotDeviceStateEnum actualState = IotDeviceStateEnum.INACTIVE; // 状态值为 0
  162 + IotDeviceStateEnum compareState = IotDeviceStateEnum.ONLINE; // 状态值为 1
  163 + IotDeviceMessage message = createDeviceMessage(actualState.getState());
146 164 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
147 165 IotSceneRuleConditionOperatorEnum.LESS_THAN.getOperator(),
148   - IotDeviceStateEnum.ONLINE.getState().toString() // 1
  166 + compareState.getState().toString()
149 167 );
150 168  
151   - // when
152   - boolean result = matcher.isMatched(message, condition);
  169 + // 调用
  170 + boolean result = matcher.matches(message, condition);
153 171  
154   - // then
  172 + // 断言
155 173 assertTrue(result);
156 174 }
157 175  
158 176 @Test
159   - public void testIsMatched_Failure_NullCondition() {
160   - // given
  177 + public void testMatches_nullCondition_fail() {
  178 + // 准备参数
161 179 IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
162 180  
163   - // when
164   - boolean result = matcher.isMatched(message, null);
  181 + // 调用
  182 + boolean result = matcher.matches(message, null);
165 183  
166   - // then
  184 + // 断言
167 185 assertFalse(result);
168 186 }
169 187  
170 188 @Test
171   - public void testIsMatched_Failure_NullConditionType() {
172   - // given
  189 + public void testMatches_nullConditionType_fail() {
  190 + // 准备参数
173 191 IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
174 192 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
175 193 condition.setType(null);
176 194  
177   - // when
178   - boolean result = matcher.isMatched(message, condition);
  195 + // 调用
  196 + boolean result = matcher.matches(message, condition);
179 197  
180   - // then
  198 + // 断言
181 199 assertFalse(result);
182 200 }
183 201  
184 202 @Test
185   - public void testIsMatched_Failure_MissingOperator() {
186   - // given
  203 + public void testMatches_missingOperator_fail() {
  204 + // 准备参数
187 205 IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
188 206 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
189 207 condition.setType(IotSceneRuleConditionTypeEnum.DEVICE_STATE.getType());
190 208 condition.setOperator(null);
191 209 condition.setParam(IotDeviceStateEnum.ONLINE.getState().toString());
192 210  
193   - // when
194   - boolean result = matcher.isMatched(message, condition);
  211 + // 调用
  212 + boolean result = matcher.matches(message, condition);
195 213  
196   - // then
  214 + // 断言
197 215 assertFalse(result);
198 216 }
199 217  
200 218 @Test
201   - public void testIsMatched_Failure_MissingParam() {
202   - // given
  219 + public void testMatches_missingParam_fail() {
  220 + // 准备参数
203 221 IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
204 222 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
205 223 condition.setType(IotSceneRuleConditionTypeEnum.DEVICE_STATE.getType());
206 224 condition.setOperator(IotSceneRuleConditionOperatorEnum.EQUALS.getOperator());
207 225 condition.setParam(null);
208 226  
209   - // when
210   - boolean result = matcher.isMatched(message, condition);
  227 + // 调用
  228 + boolean result = matcher.matches(message, condition);
211 229  
212   - // then
  230 + // 断言
213 231 assertFalse(result);
214 232 }
215 233  
216 234 @Test
217   - public void testIsMatched_Failure_NullMessage() {
218   - // given
  235 + public void testMatches_nullMessage_fail() {
  236 + // 准备参数
219 237 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
220 238 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
221 239 IotDeviceStateEnum.ONLINE.getState().toString()
222 240 );
223 241  
224   - // when
225   - boolean result = matcher.isMatched(null, condition);
  242 + // 调用
  243 + boolean result = matcher.matches(null, condition);
226 244  
227   - // then
  245 + // 断言
228 246 assertFalse(result);
229 247 }
230 248  
231 249 @Test
232   - public void testIsMatched_Failure_NullDeviceState() {
233   - // given
  250 + public void testMatches_nullDeviceState_fail() {
  251 + // 准备参数
234 252 IotDeviceMessage message = new IotDeviceMessage();
235 253 message.setParams(null);
236   -
237 254 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
238 255 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
239 256 IotDeviceStateEnum.ONLINE.getState().toString()
240 257 );
241 258  
242   - // when
243   - boolean result = matcher.isMatched(message, condition);
  259 + // 调用
  260 + boolean result = matcher.matches(message, condition);
244 261  
245   - // then
  262 + // 断言
246 263 assertFalse(result);
247 264 }
248 265  
249 266 @Test
250   - public void testIsMatched_Success_GreaterThanOrEqualsOperator() {
251   - // given
252   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState()); // 1
  267 + public void testMatches_greaterThanOrEqualsOperator_success() {
  268 + // 准备参数
  269 + IotDeviceStateEnum deviceState = IotDeviceStateEnum.ONLINE; // 状态值为 1
  270 + IotDeviceMessage message = createDeviceMessage(deviceState.getState());
253 271 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
254 272 IotSceneRuleConditionOperatorEnum.GREATER_THAN_OR_EQUALS.getOperator(),
255   - IotDeviceStateEnum.ONLINE.getState().toString() // 1
  273 + deviceState.getState().toString() // 比较值也为 1
256 274 );
257 275  
258   - // when
259   - boolean result = matcher.isMatched(message, condition);
  276 + // 调用
  277 + boolean result = matcher.matches(message, condition);
260 278  
261   - // then
  279 + // 断言
262 280 assertTrue(result);
263 281 }
264 282  
265 283 @Test
266   - public void testIsMatched_Success_LessThanOrEqualsOperator() {
267   - // given
268   - IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState()); // 1
  284 + public void testMatches_lessThanOrEqualsOperator_success() {
  285 + // 准备参数
  286 + IotDeviceStateEnum actualState = IotDeviceStateEnum.ONLINE; // 状态值为 1
  287 + IotDeviceStateEnum compareState = IotDeviceStateEnum.OFFLINE; // 状态值为 2
  288 + IotDeviceMessage message = createDeviceMessage(actualState.getState());
269 289 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
270 290 IotSceneRuleConditionOperatorEnum.LESS_THAN_OR_EQUALS.getOperator(),
271   - IotDeviceStateEnum.OFFLINE.getState().toString() // 2
  291 + compareState.getState().toString()
272 292 );
273 293  
274   - // when
275   - boolean result = matcher.isMatched(message, condition);
  294 + // 调用
  295 + boolean result = matcher.matches(message, condition);
276 296  
277   - // then
  297 + // 断言
278 298 assertTrue(result);
279 299 }
280 300  
281 301 @Test
282   - public void testIsMatched_Failure_InvalidOperator() {
283   - // given
  302 + public void testMatches_invalidOperator_fail() {
  303 + // 准备参数
284 304 IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
285 305 IotSceneRuleDO.TriggerCondition condition = new IotSceneRuleDO.TriggerCondition();
286 306 condition.setType(IotSceneRuleConditionTypeEnum.DEVICE_STATE.getType());
287   - condition.setOperator("invalid_operator");
  307 + condition.setOperator(randomString()); // 随机无效操作符
288 308 condition.setParam(IotDeviceStateEnum.ONLINE.getState().toString());
289 309  
290   - // when
291   - boolean result = matcher.isMatched(message, condition);
  310 + // 调用
  311 + boolean result = matcher.matches(message, condition);
292 312  
293   - // then
  313 + // 断言
294 314 assertFalse(result);
295 315 }
296 316  
297 317 @Test
298   - public void testIsMatched_Failure_InvalidParamFormat() {
299   - // given
  318 + public void testMatches_invalidParamFormat_fail() {
  319 + // 准备参数
300 320 IotDeviceMessage message = createDeviceMessage(IotDeviceStateEnum.ONLINE.getState());
301 321 IotSceneRuleDO.TriggerCondition condition = createValidCondition(
302 322 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
303   - "invalid_state_value"
  323 + randomString() // 随机无效状态值
304 324 );
305 325  
306   - // when
307   - boolean result = matcher.isMatched(message, condition);
  326 + // 调用
  327 + boolean result = matcher.matches(message, condition);
308 328  
309   - // then
  329 + // 断言
310 330 assertFalse(result);
311 331 }
312 332  
... ... @@ -317,6 +337,7 @@ public class DeviceStateConditionMatcherTest extends BaseMockitoUnitTest {
317 337 */
318 338 private IotDeviceMessage createDeviceMessage(Integer deviceState) {
319 339 IotDeviceMessage message = new IotDeviceMessage();
  340 + message.setDeviceId(randomLongId());
320 341 message.setParams(deviceState);
321 342 return message;
322 343 }
... ... @@ -331,4 +352,5 @@ public class DeviceStateConditionMatcherTest extends BaseMockitoUnitTest {
331 352 condition.setParam(param);
332 353 return condition;
333 354 }
  355 +
334 356 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceEventPostTriggerMatcherTest.java
... ... @@ -6,154 +6,178 @@ import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
6 6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
8 8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
9   -import org.junit.jupiter.api.BeforeEach;
10 9 import org.junit.jupiter.api.Test;
  10 +import org.mockito.InjectMocks;
11 11  
12 12 import java.util.HashMap;
13 13 import java.util.Map;
14 14  
  15 +import static cn.hutool.core.util.RandomUtil.randomInt;
  16 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  17 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
15 18 import static org.junit.jupiter.api.Assertions.*;
16 19  
17 20 /**
18   - * {@link DeviceEventPostTriggerMatcher} 的单元测试类
  21 + * {@link DeviceEventPostTriggerMatcher} 的单元测试
19 22 *
20 23 * @author HUIHUI
21 24 */
22 25 public class DeviceEventPostTriggerMatcherTest extends BaseMockitoUnitTest {
23 26  
  27 + @InjectMocks
24 28 private DeviceEventPostTriggerMatcher matcher;
25 29  
26   - @BeforeEach
27   - public void setUp() {
28   - matcher = new DeviceEventPostTriggerMatcher();
29   - }
30   -
31 30 @Test
32   - public void testGetSupportedTriggerType() {
33   - // when & then
34   - assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_EVENT_POST, matcher.getSupportedTriggerType());
  31 + public void testGetSupportedTriggerType_success() {
  32 + // 准备参数
  33 + // 无需准备参数
  34 +
  35 + // 调用
  36 + IotSceneRuleTriggerTypeEnum result = matcher.getSupportedTriggerType();
  37 +
  38 + // 断言
  39 + assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_EVENT_POST, result);
35 40 }
36 41  
37 42 @Test
38   - public void testGetPriority() {
39   - // when & then
40   - assertEquals(30, matcher.getPriority());
  43 + public void testGetPriority_success() {
  44 + // 准备参数
  45 + // 无需准备参数
  46 +
  47 + // 调用
  48 + int result = matcher.getPriority();
  49 +
  50 + // 断言
  51 + assertEquals(30, result);
41 52 }
42 53  
43 54 @Test
44   - public void testIsEnabled() {
45   - // when & then
46   - assertTrue(matcher.isEnabled());
  55 + public void testIsEnabled_success() {
  56 + // 准备参数
  57 + // 无需准备参数
  58 +
  59 + // 调用
  60 + boolean result = matcher.isEnabled();
  61 +
  62 + // 断言
  63 + assertTrue(result);
47 64 }
48 65  
49 66 @Test
50   - public void testIsMatched_Success_AlarmEvent() {
51   - // given
  67 + public void testMatches_alarmEventSuccess() {
  68 + // 准备参数
  69 + String eventIdentifier = randomString();
52 70 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
53   - .put("identifier", "alarm")
  71 + .put("identifier", eventIdentifier)
54 72 .put("value", MapUtil.builder(new HashMap<String, Object>())
55   - .put("level", "high")
56   - .put("message", "Temperature too high")
  73 + .put("level", randomString())
  74 + .put("message", randomString())
57 75 .build())
58 76 .build();
59 77 IotDeviceMessage message = createEventPostMessage(eventParams);
60   - IotSceneRuleDO.Trigger trigger = createValidTrigger("alarm");
  78 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
61 79  
62   - // when
63   - boolean result = matcher.isMatched(message, trigger);
  80 + // 调用
  81 + boolean result = matcher.matches(message, trigger);
64 82  
65   - // then
  83 + // 断言
66 84 assertTrue(result);
67 85 }
68 86  
69 87 @Test
70   - public void testIsMatched_Success_ErrorEvent() {
71   - // given
  88 + public void testMatches_errorEventSuccess() {
  89 + // 准备参数
  90 + String eventIdentifier = randomString();
72 91 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
73   - .put("identifier", "error")
  92 + .put("identifier", eventIdentifier)
74 93 .put("value", MapUtil.builder(new HashMap<String, Object>())
75   - .put("code", 500)
76   - .put("description", "System error")
  94 + .put("code", randomInt())
  95 + .put("description", randomString())
77 96 .build())
78 97 .build();
79 98 IotDeviceMessage message = createEventPostMessage(eventParams);
80   - IotSceneRuleDO.Trigger trigger = createValidTrigger("error");
  99 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
81 100  
82   - // when
83   - boolean result = matcher.isMatched(message, trigger);
  101 + // 调用
  102 + boolean result = matcher.matches(message, trigger);
84 103  
85   - // then
  104 + // 断言
86 105 assertTrue(result);
87 106 }
88 107  
89 108 @Test
90   - public void testIsMatched_Success_InfoEvent() {
91   - // given
  109 + public void testMatches_infoEventSuccess() {
  110 + // 准备参数
  111 + String eventIdentifier = randomString();
92 112 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
93   - .put("identifier", "info")
  113 + .put("identifier", eventIdentifier)
94 114 .put("value", MapUtil.builder(new HashMap<String, Object>())
95   - .put("status", "normal")
  115 + .put("status", randomString())
96 116 .put("timestamp", System.currentTimeMillis())
97 117 .build())
98 118 .build();
99 119 IotDeviceMessage message = createEventPostMessage(eventParams);
100   - IotSceneRuleDO.Trigger trigger = createValidTrigger("info");
  120 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
101 121  
102   - // when
103   - boolean result = matcher.isMatched(message, trigger);
  122 + // 调用
  123 + boolean result = matcher.matches(message, trigger);
104 124  
105   - // then
  125 + // 断言
106 126 assertTrue(result);
107 127 }
108 128  
109 129 @Test
110   - public void testIsMatched_Failure_EventIdentifierMismatch() {
111   - // given
  130 + public void testMatches_eventIdentifierMismatch() {
  131 + // 准备参数
  132 + String messageIdentifier = randomString();
  133 + String triggerIdentifier = randomString();
112 134 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
113   - .put("identifier", "alarm")
  135 + .put("identifier", messageIdentifier)
114 136 .put("value", MapUtil.builder(new HashMap<String, Object>())
115   - .put("level", "high")
  137 + .put("level", randomString())
116 138 .build())
117 139 .build();
118 140 IotDeviceMessage message = createEventPostMessage(eventParams);
119   - IotSceneRuleDO.Trigger trigger = createValidTrigger("error"); // 不匹配的事件标识符
  141 + IotSceneRuleDO.Trigger trigger = createValidTrigger(triggerIdentifier);
120 142  
121   - // when
122   - boolean result = matcher.isMatched(message, trigger);
  143 + // 调用
  144 + boolean result = matcher.matches(message, trigger);
123 145  
124   - // then
  146 + // 断言
125 147 assertFalse(result);
126 148 }
127 149  
128 150 @Test
129   - public void testIsMatched_Failure_WrongMessageMethod() {
130   - // given
  151 + public void testMatches_wrongMessageMethod() {
  152 + // 准备参数
  153 + String eventIdentifier = randomString();
131 154 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
132   - .put("identifier", "alarm")
  155 + .put("identifier", eventIdentifier)
133 156 .put("value", MapUtil.builder(new HashMap<String, Object>())
134   - .put("level", "high")
  157 + .put("level", randomString())
135 158 .build())
136 159 .build();
137 160 IotDeviceMessage message = new IotDeviceMessage();
  161 + message.setDeviceId(randomLongId());
138 162 message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod()); // 错误的方法
139 163 message.setParams(eventParams);
  164 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
140 165  
141   - IotSceneRuleDO.Trigger trigger = createValidTrigger("alarm");
142   -
143   - // when
144   - boolean result = matcher.isMatched(message, trigger);
  166 + // 调用
  167 + boolean result = matcher.matches(message, trigger);
145 168  
146   - // then
  169 + // 断言
147 170 assertFalse(result);
148 171 }
149 172  
150 173 @Test
151   - public void testIsMatched_Failure_MissingIdentifier() {
152   - // given
  174 + public void testMatches_nullTriggerIdentifier() {
  175 + // 准备参数
  176 + String eventIdentifier = randomString();
153 177 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
154   - .put("identifier", "alarm")
  178 + .put("identifier", eventIdentifier)
155 179 .put("value", MapUtil.builder(new HashMap<String, Object>())
156   - .put("level", "high")
  180 + .put("level", randomString())
157 181 .build())
158 182 .build();
159 183 IotDeviceMessage message = createEventPostMessage(eventParams);
... ... @@ -161,157 +185,166 @@ public class DeviceEventPostTriggerMatcherTest extends BaseMockitoUnitTest {
161 185 trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_EVENT_POST.getType());
162 186 trigger.setIdentifier(null); // 缺少标识符
163 187  
164   - // when
165   - boolean result = matcher.isMatched(message, trigger);
  188 + // 调用
  189 + boolean result = matcher.matches(message, trigger);
166 190  
167   - // then
  191 + // 断言
168 192 assertFalse(result);
169 193 }
170 194  
171 195 @Test
172   - public void testIsMatched_Failure_NullMessageParams() {
173   - // given
  196 + public void testMatches_nullMessageParams() {
  197 + // 准备参数
  198 + String eventIdentifier = randomString();
174 199 IotDeviceMessage message = new IotDeviceMessage();
  200 + message.setDeviceId(randomLongId());
175 201 message.setMethod(IotDeviceMessageMethodEnum.EVENT_POST.getMethod());
176 202 message.setParams(null);
  203 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
177 204  
178   - IotSceneRuleDO.Trigger trigger = createValidTrigger("alarm");
  205 + // 调用
  206 + boolean result = matcher.matches(message, trigger);
179 207  
180   - // when
181   - boolean result = matcher.isMatched(message, trigger);
182   -
183   - // then
  208 + // 断言
184 209 assertFalse(result);
185 210 }
186 211  
187 212 @Test
188   - public void testIsMatched_Failure_InvalidMessageParams() {
189   - // given
  213 + public void testMatches_invalidMessageParams() {
  214 + // 准备参数
  215 + String eventIdentifier = randomString();
190 216 IotDeviceMessage message = new IotDeviceMessage();
  217 + message.setDeviceId(randomLongId());
191 218 message.setMethod(IotDeviceMessageMethodEnum.EVENT_POST.getMethod());
192   - message.setParams("invalid-params"); // 不是 Map 类型
193   -
194   - IotSceneRuleDO.Trigger trigger = createValidTrigger("alarm");
  219 + message.setParams(randomString()); // 不是 Map 类型
  220 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
195 221  
196   - // when
197   - boolean result = matcher.isMatched(message, trigger);
  222 + // 调用
  223 + boolean result = matcher.matches(message, trigger);
198 224  
199   - // then
  225 + // 断言
200 226 assertFalse(result);
201 227 }
202 228  
203 229 @Test
204   - public void testIsMatched_Failure_MissingEventIdentifierInParams() {
205   - // given
  230 + public void testMatches_missingEventIdentifierInParams() {
  231 + // 准备参数
  232 + String eventIdentifier = randomString();
206 233 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
207 234 .put("value", MapUtil.builder(new HashMap<String, Object>())
208   - .put("level", "high")
  235 + .put("level", randomString())
209 236 .build()) // 缺少 identifier 字段
210 237 .build();
211 238 IotDeviceMessage message = createEventPostMessage(eventParams);
212   - IotSceneRuleDO.Trigger trigger = createValidTrigger("alarm");
  239 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
213 240  
214   - // when
215   - boolean result = matcher.isMatched(message, trigger);
  241 + // 调用
  242 + boolean result = matcher.matches(message, trigger);
216 243  
217   - // then
  244 + // 断言
218 245 assertFalse(result);
219 246 }
220 247  
221 248 @Test
222   - public void testIsMatched_Failure_NullTrigger() {
223   - // given
  249 + public void testMatches_nullTrigger() {
  250 + // 准备参数
  251 + String eventIdentifier = randomString();
224 252 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
225   - .put("identifier", "alarm")
  253 + .put("identifier", eventIdentifier)
226 254 .put("value", MapUtil.builder(new HashMap<String, Object>())
227   - .put("level", "high")
  255 + .put("level", randomString())
228 256 .build())
229 257 .build();
230 258 IotDeviceMessage message = createEventPostMessage(eventParams);
231 259  
232   - // when
233   - boolean result = matcher.isMatched(message, null);
  260 + // 调用
  261 + boolean result = matcher.matches(message, null);
234 262  
235   - // then
  263 + // 断言
236 264 assertFalse(result);
237 265 }
238 266  
239 267 @Test
240   - public void testIsMatched_Failure_NullTriggerType() {
241   - // given
  268 + public void testMatches_nullTriggerType() {
  269 + // 准备参数
  270 + String eventIdentifier = randomString();
242 271 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
243   - .put("identifier", "alarm")
  272 + .put("identifier", eventIdentifier)
244 273 .put("value", MapUtil.builder(new HashMap<String, Object>())
245   - .put("level", "high")
  274 + .put("level", randomString())
246 275 .build())
247 276 .build();
248 277 IotDeviceMessage message = createEventPostMessage(eventParams);
249 278 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
250 279 trigger.setType(null);
251   - trigger.setIdentifier("alarm");
  280 + trigger.setIdentifier(eventIdentifier);
252 281  
253   - // when
254   - boolean result = matcher.isMatched(message, trigger);
  282 + // 调用
  283 + boolean result = matcher.matches(message, trigger);
255 284  
256   - // then
  285 + // 断言
257 286 assertFalse(result);
258 287 }
259 288  
260 289 @Test
261   - public void testIsMatched_Success_ComplexEventValue() {
262   - // given
  290 + public void testMatches_complexEventValueSuccess() {
  291 + // 准备参数
  292 + String eventIdentifier = randomString();
263 293 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
264   - .put("identifier", "maintenance")
  294 + .put("identifier", eventIdentifier)
265 295 .put("value", MapUtil.builder(new HashMap<String, Object>())
266   - .put("type", "scheduled")
267   - .put("duration", 120)
268   - .put("components", new String[]{"motor", "sensor"})
269   - .put("priority", "medium")
  296 + .put("type", randomString())
  297 + .put("duration", randomInt())
  298 + .put("components", new String[]{randomString(), randomString()})
  299 + .put("priority", randomString())
270 300 .build())
271 301 .build();
272 302 IotDeviceMessage message = createEventPostMessage(eventParams);
273   - IotSceneRuleDO.Trigger trigger = createValidTrigger("maintenance");
  303 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
274 304  
275   - // when
276   - boolean result = matcher.isMatched(message, trigger);
  305 + // 调用
  306 + boolean result = matcher.matches(message, trigger);
277 307  
278   - // then
  308 + // 断言
279 309 assertTrue(result);
280 310 }
281 311  
282 312 @Test
283   - public void testIsMatched_Success_EmptyEventValue() {
284   - // given
  313 + public void testMatches_emptyEventValueSuccess() {
  314 + // 准备参数
  315 + String eventIdentifier = randomString();
285 316 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
286   - .put("identifier", "heartbeat")
287   - .put("value", MapUtil.of()) // 空的事件值
  317 + .put("identifier", eventIdentifier)
  318 + .put("value", MapUtil.ofEntries()) // 空的事件值
288 319 .build();
289 320 IotDeviceMessage message = createEventPostMessage(eventParams);
290   - IotSceneRuleDO.Trigger trigger = createValidTrigger("heartbeat");
  321 + IotSceneRuleDO.Trigger trigger = createValidTrigger(eventIdentifier);
291 322  
292   - // when
293   - boolean result = matcher.isMatched(message, trigger);
  323 + // 调用
  324 + boolean result = matcher.matches(message, trigger);
294 325  
295   - // then
  326 + // 断言
296 327 assertTrue(result);
297 328 }
298 329  
299 330 @Test
300   - public void testIsMatched_Success_CaseInsensitiveIdentifier() {
301   - // given
  331 + public void testMatches_caseSensitiveIdentifierMismatch() {
  332 + // 准备参数
  333 + String eventIdentifier = randomString().toUpperCase(); // 大写
  334 + String triggerIdentifier = eventIdentifier.toLowerCase(); // 小写
302 335 Map<String, Object> eventParams = MapUtil.builder(new HashMap<String, Object>())
303   - .put("identifier", "ALARM") // 大写
  336 + .put("identifier", eventIdentifier)
304 337 .put("value", MapUtil.builder(new HashMap<String, Object>())
305   - .put("level", "high")
  338 + .put("level", randomString())
306 339 .build())
307 340 .build();
308 341 IotDeviceMessage message = createEventPostMessage(eventParams);
309   - IotSceneRuleDO.Trigger trigger = createValidTrigger("alarm"); // 小写
  342 + IotSceneRuleDO.Trigger trigger = createValidTrigger(triggerIdentifier);
310 343  
311   - // when
312   - boolean result = matcher.isMatched(message, trigger);
  344 + // 调用
  345 + boolean result = matcher.matches(message, trigger);
313 346  
314   - // then
  347 + // 断言
315 348 // 根据实际实现,这里可能需要调整期望结果
316 349 // 如果实现是大小写敏感的,则应该为 false
317 350 assertFalse(result);
... ... @@ -324,6 +357,7 @@ public class DeviceEventPostTriggerMatcherTest extends BaseMockitoUnitTest {
324 357 */
325 358 private IotDeviceMessage createEventPostMessage(Map<String, Object> eventParams) {
326 359 IotDeviceMessage message = new IotDeviceMessage();
  360 + message.setDeviceId(randomLongId());
327 361 message.setMethod(IotDeviceMessageMethodEnum.EVENT_POST.getMethod());
328 362 message.setParams(eventParams);
329 363 return message;
... ... @@ -338,4 +372,5 @@ public class DeviceEventPostTriggerMatcherTest extends BaseMockitoUnitTest {
338 372 trigger.setIdentifier(identifier);
339 373 return trigger;
340 374 }
  375 +
341 376 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DevicePropertyPostTriggerMatcherTest.java
... ... @@ -7,268 +7,308 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
8 8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum;
9 9 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
10   -import org.junit.jupiter.api.BeforeEach;
11 10 import org.junit.jupiter.api.Test;
  11 +import org.mockito.InjectMocks;
12 12  
13 13 import java.util.HashMap;
14 14 import java.util.Map;
15 15  
  16 +import static cn.hutool.core.util.RandomUtil.randomDouble;
  17 +import static cn.hutool.core.util.RandomUtil.randomInt;
  18 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  19 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
16 20 import static org.junit.jupiter.api.Assertions.*;
17 21  
18 22 /**
19   - * {@link DevicePropertyPostTriggerMatcher} 的单元测试类
  23 + * {@link DevicePropertyPostTriggerMatcher} 的单元测试
20 24 *
21 25 * @author HUIHUI
22 26 */
23 27 public class DevicePropertyPostTriggerMatcherTest extends BaseMockitoUnitTest {
24 28  
  29 + @InjectMocks
25 30 private DevicePropertyPostTriggerMatcher matcher;
26 31  
27   - @BeforeEach
28   - public void setUp() {
29   - matcher = new DevicePropertyPostTriggerMatcher();
30   - }
31   -
32 32 @Test
33   - public void testGetSupportedTriggerType() {
34   - // when & then
35   - assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_PROPERTY_POST, matcher.getSupportedTriggerType());
  33 + public void testGetSupportedTriggerType_success() {
  34 + // 准备参数
  35 + // 无需准备参数
  36 +
  37 + // 调用
  38 + IotSceneRuleTriggerTypeEnum result = matcher.getSupportedTriggerType();
  39 +
  40 + // 断言
  41 + assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_PROPERTY_POST, result);
36 42 }
37 43  
38 44 @Test
39   - public void testGetPriority() {
40   - // when & then
41   - assertEquals(20, matcher.getPriority());
  45 + public void testGetPriority_success() {
  46 + // 准备参数
  47 + // 无需准备参数
  48 +
  49 + // 调用
  50 + int result = matcher.getPriority();
  51 +
  52 + // 断言
  53 + assertEquals(20, result);
42 54 }
43 55  
44 56 @Test
45   - public void testIsEnabled() {
46   - // when & then
47   - assertTrue(matcher.isEnabled());
  57 + public void testIsEnabled_success() {
  58 + // 准备参数
  59 + // 无需准备参数
  60 +
  61 + // 调用
  62 + boolean result = matcher.isEnabled();
  63 +
  64 + // 断言
  65 + assertTrue(result);
48 66 }
49 67  
50 68 @Test
51   - public void testIsMatched_Success_TemperatureProperty() {
52   - // given
  69 + public void testMatches_numericPropertyGreaterThanSuccess() {
  70 + // 准备参数
  71 + String propertyName = randomString();
  72 + Double propertyValue = 25.5;
  73 + Integer compareValue = 20;
53 74 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
54   - .put("temperature", 25.5)
  75 + .put(propertyName, propertyValue)
55 76 .build();
56 77 IotDeviceMessage message = createPropertyPostMessage(properties);
57 78 IotSceneRuleDO.Trigger trigger = createValidTrigger(
58   - "temperature",
  79 + propertyName,
59 80 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
60   - "20"
  81 + String.valueOf(compareValue)
61 82 );
62 83  
63   - // when
64   - boolean result = matcher.isMatched(message, trigger);
  84 + // 调用
  85 + boolean result = matcher.matches(message, trigger);
65 86  
66   - // then
  87 + // 断言
67 88 assertTrue(result);
68 89 }
69 90  
70 91 @Test
71   - public void testIsMatched_Success_HumidityProperty() {
72   - // given
  92 + public void testMatches_integerPropertyEqualsSuccess() {
  93 + // 准备参数
  94 + String propertyName = randomString();
  95 + Integer propertyValue = randomInt();
73 96 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
74   - .put("humidity", 60)
  97 + .put(propertyName, propertyValue)
75 98 .build();
76 99 IotDeviceMessage message = createPropertyPostMessage(properties);
77 100 IotSceneRuleDO.Trigger trigger = createValidTrigger(
78   - "humidity",
  101 + propertyName,
79 102 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
80   - "60"
  103 + String.valueOf(propertyValue)
81 104 );
82 105  
83   - // when
84   - boolean result = matcher.isMatched(message, trigger);
  106 + // 调用
  107 + boolean result = matcher.matches(message, trigger);
85 108  
86   - // then
  109 + // 断言
87 110 assertTrue(result);
88 111 }
89 112  
90 113 @Test
91   - public void testIsMatched_Failure_PropertyMismatch() {
92   - // given
  114 + public void testMatches_propertyValueNotMeetCondition() {
  115 + // 准备参数
  116 + String propertyName = randomString();
  117 + Double propertyValue = 15.0;
  118 + Integer compareValue = 20;
93 119 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
94   - .put("temperature", 15.0)
  120 + .put(propertyName, propertyValue)
95 121 .build();
96 122 IotDeviceMessage message = createPropertyPostMessage(properties);
97 123 IotSceneRuleDO.Trigger trigger = createValidTrigger(
98   - "temperature",
  124 + propertyName,
99 125 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
100   - "20"
  126 + String.valueOf(compareValue)
101 127 );
102 128  
103   - // when
104   - boolean result = matcher.isMatched(message, trigger);
  129 + // 调用
  130 + boolean result = matcher.matches(message, trigger);
105 131  
106   - // then
  132 + // 断言
107 133 assertFalse(result);
108 134 }
109 135  
110 136 @Test
111   - public void testIsMatched_Failure_PropertyNotFound() {
112   - // given
  137 + public void testMatches_propertyNotFound() {
  138 + // 准备参数
  139 + String existingProperty = randomString();
  140 + String missingProperty = randomString();
113 141 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
114   - .put("temperature", 25.5)
  142 + .put(existingProperty, randomDouble())
115 143 .build();
116 144 IotDeviceMessage message = createPropertyPostMessage(properties);
117 145 IotSceneRuleDO.Trigger trigger = createValidTrigger(
118   - "humidity", // 不存在的属性
  146 + missingProperty, // 不存在的属性
119 147 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
120   - "50"
  148 + String.valueOf(randomInt())
121 149 );
122 150  
123   - // when
124   - boolean result = matcher.isMatched(message, trigger);
  151 + // 调用
  152 + boolean result = matcher.matches(message, trigger);
125 153  
126   - // then
  154 + // 断言
127 155 assertFalse(result);
128 156 }
129 157  
130 158 @Test
131   - public void testIsMatched_Failure_WrongMessageMethod() {
132   - // given
  159 + public void testMatches_wrongMessageMethod() {
  160 + // 准备参数
  161 + String propertyName = randomString();
133 162 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
134   - .put("temperature", 25.5)
  163 + .put(propertyName, randomDouble())
135 164 .build();
136 165 IotDeviceMessage message = new IotDeviceMessage();
  166 + message.setDeviceId(randomLongId());
137 167 message.setMethod(IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod());
138 168 message.setParams(properties);
139   -
140 169 IotSceneRuleDO.Trigger trigger = createValidTrigger(
141   - "temperature",
  170 + propertyName,
142 171 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
143   - "20"
  172 + String.valueOf(randomInt())
144 173 );
145 174  
146   - // when
147   - boolean result = matcher.isMatched(message, trigger);
  175 + // 调用
  176 + boolean result = matcher.matches(message, trigger);
148 177  
149   - // then
  178 + // 断言
150 179 assertFalse(result);
151 180 }
152 181  
153 182 @Test
154   - public void testIsMatched_Failure_MissingIdentifier() {
155   - // given
  183 + public void testMatches_nullTriggerIdentifier() {
  184 + // 准备参数
  185 + String propertyName = randomString();
156 186 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
157   - .put("temperature", 25.5)
  187 + .put(propertyName, randomDouble())
158 188 .build();
159 189 IotDeviceMessage message = createPropertyPostMessage(properties);
160 190 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
161 191 trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_PROPERTY_POST.getType());
162 192 trigger.setIdentifier(null); // 缺少标识符
163 193 trigger.setOperator(IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator());
164   - trigger.setValue("20");
  194 + trigger.setValue(String.valueOf(randomInt()));
165 195  
166   - // when
167   - boolean result = matcher.isMatched(message, trigger);
  196 + // 调用
  197 + boolean result = matcher.matches(message, trigger);
168 198  
169   - // then
  199 + // 断言
170 200 assertFalse(result);
171 201 }
172 202  
173 203 @Test
174   - public void testIsMatched_Failure_NullMessageParams() {
175   - // given
  204 + public void testMatches_nullMessageParams() {
  205 + // 准备参数
  206 + String propertyName = randomString();
176 207 IotDeviceMessage message = new IotDeviceMessage();
  208 + message.setDeviceId(randomLongId());
177 209 message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod());
178 210 message.setParams(null);
179   -
180 211 IotSceneRuleDO.Trigger trigger = createValidTrigger(
181   - "temperature",
  212 + propertyName,
182 213 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
183   - "20"
  214 + String.valueOf(randomInt())
184 215 );
185 216  
186   - // when
187   - boolean result = matcher.isMatched(message, trigger);
  217 + // 调用
  218 + boolean result = matcher.matches(message, trigger);
188 219  
189   - // then
  220 + // 断言
190 221 assertFalse(result);
191 222 }
192 223  
193 224 @Test
194   - public void testIsMatched_Failure_InvalidMessageParams() {
195   - // given
  225 + public void testMatches_invalidMessageParams() {
  226 + // 准备参数
  227 + String propertyName = randomString();
196 228 IotDeviceMessage message = new IotDeviceMessage();
  229 + message.setDeviceId(randomLongId());
197 230 message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod());
198   - message.setParams("invalid-params"); // 不是 Map 类型
199   -
  231 + message.setParams(randomString()); // 不是 Map 类型
200 232 IotSceneRuleDO.Trigger trigger = createValidTrigger(
201   - "temperature",
  233 + propertyName,
202 234 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
203   - "20"
  235 + String.valueOf(randomInt())
204 236 );
205 237  
206   - // when
207   - boolean result = matcher.isMatched(message, trigger);
  238 + // 调用
  239 + boolean result = matcher.matches(message, trigger);
208 240  
209   - // then
  241 + // 断言
210 242 assertFalse(result);
211 243 }
212 244  
213 245 @Test
214   - public void testIsMatched_Success_LessThanOperator() {
215   - // given
  246 + public void testMatches_lessThanOperatorSuccess() {
  247 + // 准备参数
  248 + String propertyName = randomString();
  249 + Double propertyValue = 15.0;
  250 + Integer compareValue = 20;
216 251 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
217   - .put("temperature", 15.0)
  252 + .put(propertyName, propertyValue)
218 253 .build();
219 254 IotDeviceMessage message = createPropertyPostMessage(properties);
220 255 IotSceneRuleDO.Trigger trigger = createValidTrigger(
221   - "temperature",
  256 + propertyName,
222 257 IotSceneRuleConditionOperatorEnum.LESS_THAN.getOperator(),
223   - "20"
  258 + String.valueOf(compareValue)
224 259 );
225 260  
226   - // when
227   - boolean result = matcher.isMatched(message, trigger);
  261 + // 调用
  262 + boolean result = matcher.matches(message, trigger);
228 263  
229   - // then
  264 + // 断言
230 265 assertTrue(result);
231 266 }
232 267  
233 268 @Test
234   - public void testIsMatched_Success_NotEqualsOperator() {
235   - // given
  269 + public void testMatches_notEqualsOperatorSuccess() {
  270 + // 准备参数
  271 + String propertyName = randomString();
  272 + String propertyValue = randomString();
  273 + String compareValue = randomString();
236 274 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
237   - .put("status", "active")
  275 + .put(propertyName, propertyValue)
238 276 .build();
239 277 IotDeviceMessage message = createPropertyPostMessage(properties);
240 278 IotSceneRuleDO.Trigger trigger = createValidTrigger(
241   - "status",
  279 + propertyName,
242 280 IotSceneRuleConditionOperatorEnum.NOT_EQUALS.getOperator(),
243   - "inactive"
  281 + compareValue
244 282 );
245 283  
246   - // when
247   - boolean result = matcher.isMatched(message, trigger);
  284 + // 调用
  285 + boolean result = matcher.matches(message, trigger);
248 286  
249   - // then
  287 + // 断言
250 288 assertTrue(result);
251 289 }
252 290  
253 291 @Test
254   - public void testIsMatched_Success_MultipleProperties() {
255   - // given
  292 + public void testMatches_multiplePropertiesTargetPropertySuccess() {
  293 + // 准备参数
  294 + String targetProperty = randomString();
  295 + Integer targetValue = randomInt();
256 296 Map<String, Object> properties = MapUtil.builder(new HashMap<String, Object>())
257   - .put("temperature", 25.5)
258   - .put("humidity", 60)
259   - .put("status", "active")
  297 + .put(randomString(), randomDouble())
  298 + .put(targetProperty, targetValue)
  299 + .put(randomString(), randomString())
260 300 .build();
261 301 IotDeviceMessage message = createPropertyPostMessage(properties);
262 302 IotSceneRuleDO.Trigger trigger = createValidTrigger(
263   - "humidity",
  303 + targetProperty,
264 304 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
265   - "60"
  305 + String.valueOf(targetValue)
266 306 );
267 307  
268   - // when
269   - boolean result = matcher.isMatched(message, trigger);
  308 + // 调用
  309 + boolean result = matcher.matches(message, trigger);
270 310  
271   - // then
  311 + // 断言
272 312 assertTrue(result);
273 313 }
274 314  
... ... @@ -279,6 +319,7 @@ public class DevicePropertyPostTriggerMatcherTest extends BaseMockitoUnitTest {
279 319 */
280 320 private IotDeviceMessage createPropertyPostMessage(Map<String, Object> properties) {
281 321 IotDeviceMessage message = new IotDeviceMessage();
  322 + message.setDeviceId(randomLongId());
282 323 message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod());
283 324 message.setParams(properties);
284 325 return message;
... ... @@ -295,4 +336,5 @@ public class DevicePropertyPostTriggerMatcherTest extends BaseMockitoUnitTest {
295 336 trigger.setValue(value);
296 337 return trigger;
297 338 }
  339 +
298 340 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceServiceInvokeTriggerMatcherTest.java
... ... @@ -6,155 +6,178 @@ import cn.iocoder.yudao.module.iot.core.enums.IotDeviceMessageMethodEnum;
6 6 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
8 8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
9   -import org.junit.jupiter.api.BeforeEach;
10 9 import org.junit.jupiter.api.Test;
  10 +import org.mockito.InjectMocks;
11 11  
12 12 import java.util.HashMap;
13 13 import java.util.Map;
14 14  
  15 +import static cn.hutool.core.util.RandomUtil.*;
  16 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  17 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
15 18 import static org.junit.jupiter.api.Assertions.*;
16 19  
17 20 /**
18   - * {@link DeviceServiceInvokeTriggerMatcher} 的单元测试类
  21 + * {@link DeviceServiceInvokeTriggerMatcher} 的单元测试
19 22 *
20 23 * @author HUIHUI
21 24 */
22 25 public class DeviceServiceInvokeTriggerMatcherTest extends BaseMockitoUnitTest {
23 26  
  27 + @InjectMocks
24 28 private DeviceServiceInvokeTriggerMatcher matcher;
25 29  
26   - @BeforeEach
27   - public void setUp() {
28   - matcher = new DeviceServiceInvokeTriggerMatcher();
29   - }
30   -
31 30 @Test
32   - public void testGetSupportedTriggerType() {
33   - // when & then
34   - // TODO @puhui999:单测按照现有项目的注释风格哈;类似 // 调用;// 断言
35   - assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE, matcher.getSupportedTriggerType());
  31 + public void testGetSupportedTriggerType_success() {
  32 + // 准备参数
  33 + // 无需准备参数
  34 +
  35 + // 调用
  36 + IotSceneRuleTriggerTypeEnum result = matcher.getSupportedTriggerType();
  37 +
  38 + // 断言
  39 + assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE, result);
36 40 }
37 41  
38 42 @Test
39   - public void testGetPriority() {
40   - // when & then
41   - assertEquals(40, matcher.getPriority());
  43 + public void testGetPriority_success() {
  44 + // 准备参数
  45 + // 无需准备参数
  46 +
  47 + // 调用
  48 + int result = matcher.getPriority();
  49 +
  50 + // 断言
  51 + assertEquals(40, result);
42 52 }
43 53  
44 54 @Test
45   - public void testIsEnabled() {
46   - // when & then
47   - assertTrue(matcher.isEnabled());
  55 + public void testIsEnabled_success() {
  56 + // 准备参数
  57 + // 无需准备参数
  58 +
  59 + // 调用
  60 + boolean result = matcher.isEnabled();
  61 +
  62 + // 断言
  63 + assertTrue(result);
48 64 }
49 65  
50 66 @Test
51   - public void testIsMatched_Success_RestartService() {
52   - // given
  67 + public void testMatches_serviceInvokeSuccess() {
  68 + // 准备参数
  69 + String serviceIdentifier = randomString();
53 70 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
54   - .put("identifier", "restart")
  71 + .put("identifier", serviceIdentifier)
55 72 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
56   - .put("mode", "soft")
  73 + .put("mode", randomString())
57 74 .build())
58 75 .build();
59 76 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
60   - IotSceneRuleDO.Trigger trigger = createValidTrigger("restart");
  77 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
61 78  
62   - // when
63   - boolean result = matcher.isMatched(message, trigger);
  79 + // 调用
  80 + boolean result = matcher.matches(message, trigger);
64 81  
65   - // then
  82 + // 断言
66 83 assertTrue(result);
67 84 }
68 85  
69 86 @Test
70   - public void testIsMatched_Success_ConfigService() {
71   - // given
  87 + public void testMatches_configServiceSuccess() {
  88 + // 准备参数
  89 + String serviceIdentifier = randomString();
72 90 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
73   - .put("identifier", "config")
  91 + .put("identifier", serviceIdentifier)
74 92 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
75   - .put("interval", 30)
76   - .put("enabled", true)
77   - .put("threshold", 75.5)
  93 + .put("interval", randomInt())
  94 + .put("enabled", randomBoolean())
  95 + .put("threshold", randomDouble())
78 96 .build())
79 97 .build();
80 98 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
81   - IotSceneRuleDO.Trigger trigger = createValidTrigger("config");
  99 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
82 100  
83   - // when
84   - boolean result = matcher.isMatched(message, trigger);
  101 + // 调用
  102 + boolean result = matcher.matches(message, trigger);
85 103  
86   - // then
  104 + // 断言
87 105 assertTrue(result);
88 106 }
89 107  
90 108 @Test
91   - public void testIsMatched_Success_UpdateService() {
92   - // given
  109 + public void testMatches_updateServiceSuccess() {
  110 + // 准备参数
  111 + String serviceIdentifier = randomString();
93 112 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
94   - .put("identifier", "update")
  113 + .put("identifier", serviceIdentifier)
95 114 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
96   - .put("version", "1.2.3")
97   - .put("url", "http://example.com/firmware.bin")
  115 + .put("version", randomString())
  116 + .put("url", randomString())
98 117 .build())
99 118 .build();
100 119 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
101   - IotSceneRuleDO.Trigger trigger = createValidTrigger("update");
  120 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
102 121  
103   - // when
104   - boolean result = matcher.isMatched(message, trigger);
  122 + // 调用
  123 + boolean result = matcher.matches(message, trigger);
105 124  
106   - // then
  125 + // 断言
107 126 assertTrue(result);
108 127 }
109 128  
110 129 @Test
111   - public void testIsMatched_Failure_ServiceIdentifierMismatch() {
112   - // given
  130 + public void testMatches_serviceIdentifierMismatch() {
  131 + // 准备参数
  132 + String messageIdentifier = randomString();
  133 + String triggerIdentifier = randomString();
113 134 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
114   - .put("identifier", "restart")
  135 + .put("identifier", messageIdentifier)
115 136 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
116   - .put("mode", "soft")
  137 + .put("mode", randomString())
117 138 .build())
118 139 .build();
119 140 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
120   - IotSceneRuleDO.Trigger trigger = createValidTrigger("config"); // 不匹配的服务标识符
  141 + IotSceneRuleDO.Trigger trigger = createValidTrigger(triggerIdentifier); // 不匹配的服务标识符
121 142  
122   - // when
123   - boolean result = matcher.isMatched(message, trigger);
  143 + // 调用
  144 + boolean result = matcher.matches(message, trigger);
124 145  
125   - // then
  146 + // 断言
126 147 assertFalse(result);
127 148 }
128 149  
129 150 @Test
130   - public void testIsMatched_Failure_WrongMessageMethod() {
131   - // given
  151 + public void testMatches_wrongMessageMethod() {
  152 + // 准备参数
  153 + String serviceIdentifier = randomString();
132 154 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
133   - .put("identifier", "restart")
  155 + .put("identifier", serviceIdentifier)
134 156 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
135   - .put("mode", "soft")
  157 + .put("mode", randomString())
136 158 .build())
137 159 .build();
138 160 IotDeviceMessage message = new IotDeviceMessage();
  161 + message.setDeviceId(randomLongId());
139 162 message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod()); // 错误的方法
140 163 message.setParams(serviceParams);
  164 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
141 165  
142   - IotSceneRuleDO.Trigger trigger = createValidTrigger("restart");
143   -
144   - // when
145   - boolean result = matcher.isMatched(message, trigger);
  166 + // 调用
  167 + boolean result = matcher.matches(message, trigger);
146 168  
147   - // then
  169 + // 断言
148 170 assertFalse(result);
149 171 }
150 172  
151 173 @Test
152   - public void testIsMatched_Failure_MissingIdentifier() {
153   - // given
  174 + public void testMatches_nullTriggerIdentifier() {
  175 + // 准备参数
  176 + String serviceIdentifier = randomString();
154 177 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
155   - .put("identifier", "restart")
  178 + .put("identifier", serviceIdentifier)
156 179 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
157   - .put("mode", "soft")
  180 + .put("mode", randomString())
158 181 .build())
159 182 .build();
160 183 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
... ... @@ -162,178 +185,188 @@ public class DeviceServiceInvokeTriggerMatcherTest extends BaseMockitoUnitTest {
162 185 trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_SERVICE_INVOKE.getType());
163 186 trigger.setIdentifier(null); // 缺少标识符
164 187  
165   - // when
166   - boolean result = matcher.isMatched(message, trigger);
  188 + // 调用
  189 + boolean result = matcher.matches(message, trigger);
167 190  
168   - // then
  191 + // 断言
169 192 assertFalse(result);
170 193 }
171 194  
172 195 @Test
173   - public void testIsMatched_Failure_NullMessageParams() {
174   - // given
  196 + public void testMatches_nullMessageParams() {
  197 + // 准备参数
  198 + String serviceIdentifier = randomString();
175 199 IotDeviceMessage message = new IotDeviceMessage();
  200 + message.setDeviceId(randomLongId());
176 201 message.setMethod(IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod());
177 202 message.setParams(null);
  203 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
178 204  
179   - IotSceneRuleDO.Trigger trigger = createValidTrigger("restart");
  205 + // 调用
  206 + boolean result = matcher.matches(message, trigger);
180 207  
181   - // when
182   - boolean result = matcher.isMatched(message, trigger);
183   -
184   - // then
  208 + // 断言
185 209 assertFalse(result);
186 210 }
187 211  
188 212 @Test
189   - public void testIsMatched_Failure_InvalidMessageParams() {
190   - // given
  213 + public void testMatches_invalidMessageParams() {
  214 + // 准备参数
  215 + String serviceIdentifier = randomString();
191 216 IotDeviceMessage message = new IotDeviceMessage();
  217 + message.setDeviceId(randomLongId());
192 218 message.setMethod(IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod());
193   - message.setParams("invalid-params"); // 不是 Map 类型
194   -
195   - IotSceneRuleDO.Trigger trigger = createValidTrigger("restart");
  219 + message.setParams(randomString()); // 不是 Map 类型
  220 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
196 221  
197   - // when
198   - boolean result = matcher.isMatched(message, trigger);
  222 + // 调用
  223 + boolean result = matcher.matches(message, trigger);
199 224  
200   - // then
  225 + // 断言
201 226 assertFalse(result);
202 227 }
203 228  
204 229 @Test
205   - public void testIsMatched_Failure_MissingServiceIdentifierInParams() {
206   - // given
  230 + public void testMatches_missingServiceIdentifierInParams() {
  231 + // 准备参数
  232 + String serviceIdentifier = randomString();
207 233 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
208 234 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
209   - .put("mode", "soft")
  235 + .put("mode", randomString())
210 236 .build()) // 缺少 identifier 字段
211 237 .build();
212 238 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
213   - IotSceneRuleDO.Trigger trigger = createValidTrigger("restart");
  239 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
214 240  
215   - // when
216   - boolean result = matcher.isMatched(message, trigger);
  241 + // 调用
  242 + boolean result = matcher.matches(message, trigger);
217 243  
218   - // then
  244 + // 断言
219 245 assertFalse(result);
220 246 }
221 247  
222 248 @Test
223   - public void testIsMatched_Failure_NullTrigger() {
224   - // given
  249 + public void testMatches_nullTrigger() {
  250 + // 准备参数
  251 + String serviceIdentifier = randomString();
225 252 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
226   - .put("identifier", "restart")
  253 + .put("identifier", serviceIdentifier)
227 254 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
228   - .put("mode", "soft")
  255 + .put("mode", randomString())
229 256 .build())
230 257 .build();
231 258 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
232 259  
233   - // when
234   - boolean result = matcher.isMatched(message, null);
  260 + // 调用
  261 + boolean result = matcher.matches(message, null);
235 262  
236   - // then
  263 + // 断言
237 264 assertFalse(result);
238 265 }
239 266  
240 267 @Test
241   - public void testIsMatched_Failure_NullTriggerType() {
242   - // given
  268 + public void testMatches_nullTriggerType() {
  269 + // 准备参数
  270 + String serviceIdentifier = randomString();
243 271 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
244   - .put("identifier", "restart")
  272 + .put("identifier", serviceIdentifier)
245 273 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
246   - .put("mode", "soft")
  274 + .put("mode", randomString())
247 275 .build())
248 276 .build();
249 277 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
250 278 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
251 279 trigger.setType(null);
252   - trigger.setIdentifier("restart");
  280 + trigger.setIdentifier(serviceIdentifier);
253 281  
254   - // when
255   - boolean result = matcher.isMatched(message, trigger);
  282 + // 调用
  283 + boolean result = matcher.matches(message, trigger);
256 284  
257   - // then
  285 + // 断言
258 286 assertFalse(result);
259 287 }
260 288  
261 289 @Test
262   - public void testIsMatched_Success_EmptyInputData() {
263   - // given
  290 + public void testMatches_emptyInputDataSuccess() {
  291 + // 准备参数
  292 + String serviceIdentifier = randomString();
264 293 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
265   - .put("identifier", "ping")
266   - .put("inputData", MapUtil.of()) // 空的输入数据
  294 + .put("identifier", serviceIdentifier)
  295 + .put("inputData", MapUtil.ofEntries()) // 空的输入数据
267 296 .build();
268 297 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
269   - IotSceneRuleDO.Trigger trigger = createValidTrigger("ping");
  298 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
270 299  
271   - // when
272   - boolean result = matcher.isMatched(message, trigger);
  300 + // 调用
  301 + boolean result = matcher.matches(message, trigger);
273 302  
274   - // then
  303 + // 断言
275 304 assertTrue(result);
276 305 }
277 306  
278 307 @Test
279   - public void testIsMatched_Success_NoInputData() {
280   - // given
  308 + public void testMatches_noInputDataSuccess() {
  309 + // 准备参数
  310 + String serviceIdentifier = randomString();
281 311 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
282   - .put("identifier", "status")
  312 + .put("identifier", serviceIdentifier)
283 313 // 没有 inputData 字段
284 314 .build();
285 315 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
286   - IotSceneRuleDO.Trigger trigger = createValidTrigger("status");
  316 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
287 317  
288   - // when
289   - boolean result = matcher.isMatched(message, trigger);
  318 + // 调用
  319 + boolean result = matcher.matches(message, trigger);
290 320  
291   - // then
  321 + // 断言
292 322 assertTrue(result);
293 323 }
294 324  
295 325 @Test
296   - public void testIsMatched_Success_ComplexInputData() {
297   - // given
  326 + public void testMatches_complexInputDataSuccess() {
  327 + // 准备参数
  328 + String serviceIdentifier = randomString();
298 329 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
299   - .put("identifier", "calibrate")
  330 + .put("identifier", serviceIdentifier)
300 331 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
301   - .put("sensors", new String[]{"temperature", "humidity", "pressure"})
302   - .put("precision", 0.01)
303   - .put("duration", 300)
304   - .put("autoSave", true)
  332 + .put("sensors", new String[]{randomString(), randomString(), randomString()})
  333 + .put("precision", randomDouble())
  334 + .put("duration", randomInt())
  335 + .put("autoSave", randomBoolean())
305 336 .put("config", MapUtil.builder(new HashMap<String, Object>())
306   - .put("mode", "auto")
307   - .put("level", "high")
  337 + .put("mode", randomString())
  338 + .put("level", randomString())
308 339 .build())
309 340 .build())
310 341 .build();
311 342 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
312   - IotSceneRuleDO.Trigger trigger = createValidTrigger("calibrate");
  343 + IotSceneRuleDO.Trigger trigger = createValidTrigger(serviceIdentifier);
313 344  
314   - // when
315   - boolean result = matcher.isMatched(message, trigger);
  345 + // 调用
  346 + boolean result = matcher.matches(message, trigger);
316 347  
317   - // then
  348 + // 断言
318 349 assertTrue(result);
319 350 }
320 351  
321 352 @Test
322   - public void testIsMatched_Success_CaseInsensitiveIdentifier() {
323   - // given
  353 + public void testMatches_caseSensitiveIdentifierMismatch() {
  354 + // 准备参数
  355 + String serviceIdentifier = randomString().toUpperCase(); // 大写
  356 + String triggerIdentifier = serviceIdentifier.toLowerCase(); // 小写
324 357 Map<String, Object> serviceParams = MapUtil.builder(new HashMap<String, Object>())
325   - .put("identifier", "RESTART") // 大写
  358 + .put("identifier", serviceIdentifier)
326 359 .put("inputData", MapUtil.builder(new HashMap<String, Object>())
327   - .put("mode", "soft")
  360 + .put("mode", randomString())
328 361 .build())
329 362 .build();
330 363 IotDeviceMessage message = createServiceInvokeMessage(serviceParams);
331   - IotSceneRuleDO.Trigger trigger = createValidTrigger("restart"); // 小写
  364 + IotSceneRuleDO.Trigger trigger = createValidTrigger(triggerIdentifier);
332 365  
333   - // when
334   - boolean result = matcher.isMatched(message, trigger);
  366 + // 调用
  367 + boolean result = matcher.matches(message, trigger);
335 368  
336   - // then
  369 + // 断言
337 370 // 根据实际实现,这里可能需要调整期望结果
338 371 // 如果实现是大小写敏感的,则应该为 false
339 372 assertFalse(result);
... ... @@ -346,6 +379,7 @@ public class DeviceServiceInvokeTriggerMatcherTest extends BaseMockitoUnitTest {
346 379 */
347 380 private IotDeviceMessage createServiceInvokeMessage(Map<String, Object> serviceParams) {
348 381 IotDeviceMessage message = new IotDeviceMessage();
  382 + message.setDeviceId(randomLongId());
349 383 message.setMethod(IotDeviceMessageMethodEnum.SERVICE_INVOKE.getMethod());
350 384 message.setParams(serviceParams);
351 385 return message;
... ... @@ -360,4 +394,5 @@ public class DeviceServiceInvokeTriggerMatcherTest extends BaseMockitoUnitTest {
360 394 trigger.setIdentifier(identifier);
361 395 return trigger;
362 396 }
  397 +
363 398 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/DeviceStateUpdateTriggerMatcherTest.java
... ... @@ -7,216 +7,231 @@ import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
7 7 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
8 8 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleConditionOperatorEnum;
9 9 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
10   -import org.junit.jupiter.api.BeforeEach;
11 10 import org.junit.jupiter.api.Test;
  11 +import org.mockito.InjectMocks;
12 12  
  13 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
13 14 import static org.junit.jupiter.api.Assertions.*;
14 15  
15 16 /**
16   - * {@link DeviceStateUpdateTriggerMatcher} 的单元测试类
  17 + * {@link DeviceStateUpdateTriggerMatcher} 的单元测试
17 18 *
18 19 * @author HUIHUI
19 20 */
20 21 public class DeviceStateUpdateTriggerMatcherTest extends BaseMockitoUnitTest {
21 22  
  23 + @InjectMocks
22 24 private DeviceStateUpdateTriggerMatcher matcher;
23 25  
24   - @BeforeEach
25   - public void setUp() {
26   - matcher = new DeviceStateUpdateTriggerMatcher();
27   - }
28   -
29 26 @Test
30   - public void testGetSupportedTriggerType() {
31   - // when & then
32   - assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE, matcher.getSupportedTriggerType());
  27 + public void testGetSupportedTriggerType_success() {
  28 + // 准备参数
  29 + // 无需准备参数
  30 +
  31 + // 调用
  32 + IotSceneRuleTriggerTypeEnum result = matcher.getSupportedTriggerType();
  33 +
  34 + // 断言
  35 + assertEquals(IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE, result);
33 36 }
34 37  
35 38 @Test
36   - public void testGetPriority() {
37   - // when & then
38   - assertEquals(10, matcher.getPriority());
  39 + public void testGetPriority_success() {
  40 + // 准备参数
  41 + // 无需准备参数
  42 +
  43 + // 调用
  44 + int result = matcher.getPriority();
  45 +
  46 + // 断言
  47 + assertEquals(10, result);
39 48 }
40 49  
41 50 @Test
42   - public void testIsEnabled() {
43   - // when & then
44   - assertTrue(matcher.isEnabled());
  51 + public void testIsEnabled_success() {
  52 + // 准备参数
  53 + // 无需准备参数
  54 +
  55 + // 调用
  56 + boolean result = matcher.isEnabled();
  57 +
  58 + // 断言
  59 + assertTrue(result);
45 60 }
46 61  
47 62 @Test
48   - public void testIsMatched_Success_OnlineState() {
49   - // given
  63 + public void testMatches_onlineStateSuccess() {
  64 + // 准备参数
50 65 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
51 66 IotSceneRuleDO.Trigger trigger = createValidTrigger(
52 67 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
53 68 IotDeviceStateEnum.ONLINE.getState().toString()
54 69 );
55 70  
56   - // when
57   - boolean result = matcher.isMatched(message, trigger);
  71 + // 调用
  72 + boolean result = matcher.matches(message, trigger);
58 73  
59   - // then
  74 + // 断言
60 75 assertTrue(result);
61 76 }
62 77  
63 78 @Test
64   - public void testIsMatched_Success_OfflineState() {
65   - // given
  79 + public void testMatches_offlineStateSuccess() {
  80 + // 准备参数
66 81 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.OFFLINE.getState());
67 82 IotSceneRuleDO.Trigger trigger = createValidTrigger(
68 83 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
69 84 IotDeviceStateEnum.OFFLINE.getState().toString()
70 85 );
71 86  
72   - // when
73   - boolean result = matcher.isMatched(message, trigger);
  87 + // 调用
  88 + boolean result = matcher.matches(message, trigger);
74 89  
75   - // then
  90 + // 断言
76 91 assertTrue(result);
77 92 }
78 93  
79 94 @Test
80   - public void testIsMatched_Failure_StateMismatch() {
81   - // given
  95 + public void testMatches_stateMismatch() {
  96 + // 准备参数
82 97 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
83 98 IotSceneRuleDO.Trigger trigger = createValidTrigger(
84 99 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
85 100 IotDeviceStateEnum.OFFLINE.getState().toString()
86 101 );
87 102  
88   - // when
89   - boolean result = matcher.isMatched(message, trigger);
  103 + // 调用
  104 + boolean result = matcher.matches(message, trigger);
90 105  
91   - // then
  106 + // 断言
92 107 assertFalse(result);
93 108 }
94 109  
95 110 @Test
96   - public void testIsMatched_Failure_NullTrigger() {
97   - // given
  111 + public void testMatches_nullTrigger() {
  112 + // 准备参数
98 113 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
99 114  
100   - // when
101   - boolean result = matcher.isMatched(message, null);
  115 + // 调用
  116 + boolean result = matcher.matches(message, null);
102 117  
103   - // then
  118 + // 断言
104 119 assertFalse(result);
105 120 }
106 121  
107 122 @Test
108   - public void testIsMatched_Failure_NullTriggerType() {
109   - // given
  123 + public void testMatches_nullTriggerType() {
  124 + // 准备参数
110 125 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
111 126 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
112 127 trigger.setType(null);
113 128  
114   - // when
115   - boolean result = matcher.isMatched(message, trigger);
  129 + // 调用
  130 + boolean result = matcher.matches(message, trigger);
116 131  
117   - // then
  132 + // 断言
118 133 assertFalse(result);
119 134 }
120 135  
121 136 @Test
122   - public void testIsMatched_Failure_WrongMessageMethod() {
123   - // given
  137 + public void testMatches_wrongMessageMethod() {
  138 + // 准备参数
124 139 IotDeviceMessage message = new IotDeviceMessage();
  140 + message.setDeviceId(randomLongId());
125 141 message.setMethod(IotDeviceMessageMethodEnum.PROPERTY_POST.getMethod());
126 142 message.setParams(IotDeviceStateEnum.ONLINE.getState());
127   -
128 143 IotSceneRuleDO.Trigger trigger = createValidTrigger(
129 144 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
130 145 IotDeviceStateEnum.ONLINE.getState().toString()
131 146 );
132 147  
133   - // when
134   - boolean result = matcher.isMatched(message, trigger);
  148 + // 调用
  149 + boolean result = matcher.matches(message, trigger);
135 150  
136   - // then
  151 + // 断言
137 152 assertFalse(result);
138 153 }
139 154  
140 155 @Test
141   - public void testIsMatched_Failure_MissingOperator() {
142   - // given
  156 + public void testMatches_nullTriggerOperator() {
  157 + // 准备参数
143 158 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
144 159 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
145 160 trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE.getType());
146 161 trigger.setOperator(null);
147 162 trigger.setValue(IotDeviceStateEnum.ONLINE.getState().toString());
148 163  
149   - // when
150   - boolean result = matcher.isMatched(message, trigger);
  164 + // 调用
  165 + boolean result = matcher.matches(message, trigger);
151 166  
152   - // then
  167 + // 断言
153 168 assertFalse(result);
154 169 }
155 170  
156 171 @Test
157   - public void testIsMatched_Failure_MissingValue() {
158   - // given
  172 + public void testMatches_nullTriggerValue() {
  173 + // 准备参数
159 174 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
160 175 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
161 176 trigger.setType(IotSceneRuleTriggerTypeEnum.DEVICE_STATE_UPDATE.getType());
162 177 trigger.setOperator(IotSceneRuleConditionOperatorEnum.EQUALS.getOperator());
163 178 trigger.setValue(null);
164 179  
165   - // when
166   - boolean result = matcher.isMatched(message, trigger);
  180 + // 调用
  181 + boolean result = matcher.matches(message, trigger);
167 182  
168   - // then
  183 + // 断言
169 184 assertFalse(result);
170 185 }
171 186  
172 187 @Test
173   - public void testIsMatched_Failure_NullMessageParams() {
174   - // given
  188 + public void testMatches_nullMessageParams() {
  189 + // 准备参数
175 190 IotDeviceMessage message = new IotDeviceMessage();
  191 + message.setDeviceId(randomLongId());
176 192 message.setMethod(IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod());
177 193 message.setParams(null);
178   -
179 194 IotSceneRuleDO.Trigger trigger = createValidTrigger(
180 195 IotSceneRuleConditionOperatorEnum.EQUALS.getOperator(),
181 196 IotDeviceStateEnum.ONLINE.getState().toString()
182 197 );
183 198  
184   - // when
185   - boolean result = matcher.isMatched(message, trigger);
  199 + // 调用
  200 + boolean result = matcher.matches(message, trigger);
186 201  
187   - // then
  202 + // 断言
188 203 assertFalse(result);
189 204 }
190 205  
191 206 @Test
192   - public void testIsMatched_Success_GreaterThanOperator() {
193   - // given
  207 + public void testMatches_greaterThanOperatorSuccess() {
  208 + // 准备参数
194 209 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
195 210 IotSceneRuleDO.Trigger trigger = createValidTrigger(
196 211 IotSceneRuleConditionOperatorEnum.GREATER_THAN.getOperator(),
197 212 IotDeviceStateEnum.INACTIVE.getState().toString()
198 213 );
199 214  
200   - // when
201   - boolean result = matcher.isMatched(message, trigger);
  215 + // 调用
  216 + boolean result = matcher.matches(message, trigger);
202 217  
203   - // then
  218 + // 断言
204 219 assertTrue(result);
205 220 }
206 221  
207 222 @Test
208   - public void testIsMatched_Success_NotEqualsOperator() {
209   - // given
  223 + public void testMatches_notEqualsOperatorSuccess() {
  224 + // 准备参数
210 225 IotDeviceMessage message = createStateUpdateMessage(IotDeviceStateEnum.ONLINE.getState());
211 226 IotSceneRuleDO.Trigger trigger = createValidTrigger(
212 227 IotSceneRuleConditionOperatorEnum.NOT_EQUALS.getOperator(),
213 228 IotDeviceStateEnum.OFFLINE.getState().toString()
214 229 );
215 230  
216   - // when
217   - boolean result = matcher.isMatched(message, trigger);
  231 + // 调用
  232 + boolean result = matcher.matches(message, trigger);
218 233  
219   - // then
  234 + // 断言
220 235 assertTrue(result);
221 236 }
222 237  
... ... @@ -227,6 +242,7 @@ public class DeviceStateUpdateTriggerMatcherTest extends BaseMockitoUnitTest {
227 242 */
228 243 private IotDeviceMessage createStateUpdateMessage(Integer state) {
229 244 IotDeviceMessage message = new IotDeviceMessage();
  245 + message.setDeviceId(randomLongId());
230 246 message.setMethod(IotDeviceMessageMethodEnum.STATE_UPDATE.getMethod());
231 247 message.setParams(state);
232 248 return message;
... ... @@ -242,4 +258,5 @@ public class DeviceStateUpdateTriggerMatcherTest extends BaseMockitoUnitTest {
242 258 trigger.setValue(value);
243 259 return trigger;
244 260 }
  261 +
245 262 }
... ...
yudao-module-iot/yudao-module-iot-biz/src/test/java/cn/iocoder/yudao/module/iot/service/rule/scene/matcher/trigger/TimerTriggerMatcherTest.java
... ... @@ -4,231 +4,266 @@ import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
4 4 import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
5 5 import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotSceneRuleDO;
6 6 import cn.iocoder.yudao.module.iot.enums.rule.IotSceneRuleTriggerTypeEnum;
7   -import org.junit.jupiter.api.BeforeEach;
8 7 import org.junit.jupiter.api.Test;
  8 +import org.mockito.InjectMocks;
9 9  
  10 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomLongId;
  11 +import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.randomString;
10 12 import static org.junit.jupiter.api.Assertions.*;
11 13  
12 14 /**
13   - * {@link TimerTriggerMatcher} 的单元测试类
  15 + * {@link TimerTriggerMatcher} 的单元测试
14 16 *
15 17 * @author HUIHUI
16 18 */
17 19 public class TimerTriggerMatcherTest extends BaseMockitoUnitTest {
18 20  
  21 + @InjectMocks
19 22 private TimerTriggerMatcher matcher;
20 23  
21   - @BeforeEach
22   - public void setUp() {
23   - matcher = new TimerTriggerMatcher();
24   - }
25   -
26 24 @Test
27   - public void testGetSupportedTriggerType() {
28   - // when & then
29   - assertEquals(IotSceneRuleTriggerTypeEnum.TIMER, matcher.getSupportedTriggerType());
  25 + public void testGetSupportedTriggerType_success() {
  26 + // 准备参数
  27 + // 无需准备参数
  28 +
  29 + // 调用
  30 + IotSceneRuleTriggerTypeEnum result = matcher.getSupportedTriggerType();
  31 +
  32 + // 断言
  33 + assertEquals(IotSceneRuleTriggerTypeEnum.TIMER, result);
30 34 }
31 35  
32 36 @Test
33   - public void testGetPriority() {
34   - // when & then
35   - assertEquals(50, matcher.getPriority());
  37 + public void testGetPriority_success() {
  38 + // 准备参数
  39 + // 无需准备参数
  40 +
  41 + // 调用
  42 + int result = matcher.getPriority();
  43 +
  44 + // 断言
  45 + assertEquals(50, result);
36 46 }
37 47  
38 48 @Test
39   - public void testIsEnabled() {
40   - // when & then
41   - assertTrue(matcher.isEnabled());
  49 + public void testIsEnabled_success() {
  50 + // 准备参数
  51 + // 无需准备参数
  52 +
  53 + // 调用
  54 + boolean result = matcher.isEnabled();
  55 +
  56 + // 断言
  57 + assertTrue(result);
42 58 }
43 59  
44 60 @Test
45   - public void testIsMatched_Success_ValidCronExpression() {
46   - // given
47   - IotDeviceMessage message = new IotDeviceMessage();
48   - IotSceneRuleDO.Trigger trigger = createValidTrigger("0 0 12 * * ?"); // 每天中午12点
  61 + public void testMatches_validCronExpressionSuccess() {
  62 + // 准备参数
  63 + IotDeviceMessage message = createDeviceMessage();
  64 + String cronExpression = "0 0 12 * * ?"; // 每天中午12点
  65 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
49 66  
50   - // when
51   - boolean result = matcher.isMatched(message, trigger);
  67 + // 调用
  68 + boolean result = matcher.matches(message, trigger);
52 69  
53   - // then
  70 + // 断言
54 71 assertTrue(result);
55 72 }
56 73  
57 74 @Test
58   - public void testIsMatched_Success_EveryMinuteCron() {
59   - // given
60   - IotDeviceMessage message = new IotDeviceMessage();
61   - IotSceneRuleDO.Trigger trigger = createValidTrigger("0 * * * * ?"); // 每分钟
  75 + public void testMatches_everyMinuteCronSuccess() {
  76 + // 准备参数
  77 + IotDeviceMessage message = createDeviceMessage();
  78 + String cronExpression = "0 * * * * ?"; // 每分钟
  79 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
62 80  
63   - // when
64   - boolean result = matcher.isMatched(message, trigger);
  81 + // 调用
  82 + boolean result = matcher.matches(message, trigger);
65 83  
66   - // then
  84 + // 断言
67 85 assertTrue(result);
68 86 }
69 87  
70 88 @Test
71   - public void testIsMatched_Success_WeekdaysCron() {
72   - // given
73   - IotDeviceMessage message = new IotDeviceMessage();
74   - IotSceneRuleDO.Trigger trigger = createValidTrigger("0 0 9 ? * MON-FRI"); // 工作日上午9点
  89 + public void testMatches_weekdaysCronSuccess() {
  90 + // 准备参数
  91 + IotDeviceMessage message = createDeviceMessage();
  92 + String cronExpression = "0 0 9 ? * MON-FRI"; // 工作日上午9点
  93 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
75 94  
76   - // when
77   - boolean result = matcher.isMatched(message, trigger);
  95 + // 调用
  96 + boolean result = matcher.matches(message, trigger);
78 97  
79   - // then
  98 + // 断言
80 99 assertTrue(result);
81 100 }
82 101  
83 102 @Test
84   - public void testIsMatched_Failure_InvalidCronExpression() {
85   - // given
86   - IotDeviceMessage message = new IotDeviceMessage();
87   - IotSceneRuleDO.Trigger trigger = createValidTrigger("invalid-cron-expression");
  103 + public void testMatches_invalidCronExpression() {
  104 + // 准备参数
  105 + IotDeviceMessage message = createDeviceMessage();
  106 + String cronExpression = randomString(); // 随机无效的 cron 表达式
  107 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
88 108  
89   - // when
90   - boolean result = matcher.isMatched(message, trigger);
  109 + // 调用
  110 + boolean result = matcher.matches(message, trigger);
91 111  
92   - // then
  112 + // 断言
93 113 assertFalse(result);
94 114 }
95 115  
96 116 @Test
97   - public void testIsMatched_Failure_EmptyCronExpression() {
98   - // given
99   - IotDeviceMessage message = new IotDeviceMessage();
100   - IotSceneRuleDO.Trigger trigger = createValidTrigger("");
  117 + public void testMatches_emptyCronExpression() {
  118 + // 准备参数
  119 + IotDeviceMessage message = createDeviceMessage();
  120 + String cronExpression = ""; // 空的 cron 表达式
  121 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
101 122  
102   - // when
103   - boolean result = matcher.isMatched(message, trigger);
  123 + // 调用
  124 + boolean result = matcher.matches(message, trigger);
104 125  
105   - // then
  126 + // 断言
106 127 assertFalse(result);
107 128 }
108 129  
109 130 @Test
110   - public void testIsMatched_Failure_NullCronExpression() {
111   - // given
112   - IotDeviceMessage message = new IotDeviceMessage();
  131 + public void testMatches_nullCronExpression() {
  132 + // 准备参数
  133 + IotDeviceMessage message = createDeviceMessage();
113 134 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
114 135 trigger.setType(IotSceneRuleTriggerTypeEnum.TIMER.getType());
115 136 trigger.setCronExpression(null);
116 137  
117   - // when
118   - boolean result = matcher.isMatched(message, trigger);
  138 + // 调用
  139 + boolean result = matcher.matches(message, trigger);
119 140  
120   - // then
  141 + // 断言
121 142 assertFalse(result);
122 143 }
123 144  
124 145 @Test
125   - public void testIsMatched_Failure_NullTrigger() {
126   - // given
127   - IotDeviceMessage message = new IotDeviceMessage();
  146 + public void testMatches_nullTrigger() {
  147 + // 准备参数
  148 + IotDeviceMessage message = createDeviceMessage();
128 149  
129   - // when
130   - boolean result = matcher.isMatched(message, null);
  150 + // 调用
  151 + boolean result = matcher.matches(message, null);
131 152  
132   - // then
  153 + // 断言
133 154 assertFalse(result);
134 155 }
135 156  
136 157 @Test
137   - public void testIsMatched_Failure_NullTriggerType() {
138   - // given
139   - IotDeviceMessage message = new IotDeviceMessage();
  158 + public void testMatches_nullTriggerType() {
  159 + // 准备参数
  160 + IotDeviceMessage message = createDeviceMessage();
140 161 IotSceneRuleDO.Trigger trigger = new IotSceneRuleDO.Trigger();
141 162 trigger.setType(null);
142 163 trigger.setCronExpression("0 0 12 * * ?");
143 164  
144   - // when
145   - boolean result = matcher.isMatched(message, trigger);
  165 + // 调用
  166 + boolean result = matcher.matches(message, trigger);
146 167  
147   - // then
  168 + // 断言
148 169 assertFalse(result);
149 170 }
150 171  
151 172 @Test
152   - public void testIsMatched_Success_ComplexCronExpression() {
153   - // given
154   - IotDeviceMessage message = new IotDeviceMessage();
155   - IotSceneRuleDO.Trigger trigger = createValidTrigger("0 15 10 ? * 6#3"); // 每月第三个星期五上午10:15
  173 + public void testMatches_complexCronExpressionSuccess() {
  174 + // 准备参数
  175 + IotDeviceMessage message = createDeviceMessage();
  176 + String cronExpression = "0 15 10 ? * 6#3"; // 每月第三个星期五上午10:15
  177 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
156 178  
157   - // when
158   - boolean result = matcher.isMatched(message, trigger);
  179 + // 调用
  180 + boolean result = matcher.matches(message, trigger);
159 181  
160   - // then
  182 + // 断言
161 183 assertTrue(result);
162 184 }
163 185  
164 186 @Test
165   - public void testIsMatched_Failure_IncorrectCronFormat() {
166   - // given
167   - IotDeviceMessage message = new IotDeviceMessage();
168   - IotSceneRuleDO.Trigger trigger = createValidTrigger("0 0 12 * *"); // 缺少字段
  187 + public void testMatches_incorrectCronFormat() {
  188 + // 准备参数
  189 + IotDeviceMessage message = createDeviceMessage();
  190 + String cronExpression = "0 0 12 * *"; // 缺少字段的 cron 表达式
  191 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
169 192  
170   - // when
171   - boolean result = matcher.isMatched(message, trigger);
  193 + // 调用
  194 + boolean result = matcher.matches(message, trigger);
172 195  
173   - // then
  196 + // 断言
174 197 assertFalse(result);
175 198 }
176 199  
177 200 @Test
178   - public void testIsMatched_Success_SpecificDateCron() {
179   - // given
180   - IotDeviceMessage message = new IotDeviceMessage();
181   - IotSceneRuleDO.Trigger trigger = createValidTrigger("0 0 0 1 1 ? 2025"); // 2025年1月1日午夜
  201 + public void testMatches_specificDateCronSuccess() {
  202 + // 准备参数
  203 + IotDeviceMessage message = createDeviceMessage();
  204 + String cronExpression = "0 0 0 1 1 ? 2025"; // 2025年1月1日午夜
  205 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
182 206  
183   - // when
184   - boolean result = matcher.isMatched(message, trigger);
  207 + // 调用
  208 + boolean result = matcher.matches(message, trigger);
185 209  
186   - // then
  210 + // 断言
187 211 assertTrue(result);
188 212 }
189 213  
190 214 @Test
191   - public void testIsMatched_Success_EverySecondCron() {
192   - // given
193   - IotDeviceMessage message = new IotDeviceMessage();
194   - IotSceneRuleDO.Trigger trigger = createValidTrigger("* * * * * ?"); // 每秒
  215 + public void testMatches_everySecondCronSuccess() {
  216 + // 准备参数
  217 + IotDeviceMessage message = createDeviceMessage();
  218 + String cronExpression = "* * * * * ?"; // 每秒执行
  219 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
195 220  
196   - // when
197   - boolean result = matcher.isMatched(message, trigger);
  221 + // 调用
  222 + boolean result = matcher.matches(message, trigger);
198 223  
199   - // then
  224 + // 断言
200 225 assertTrue(result);
201 226 }
202 227  
203 228 @Test
204   - public void testIsMatched_Failure_InvalidCharactersCron() {
205   - // given
206   - IotDeviceMessage message = new IotDeviceMessage();
207   - IotSceneRuleDO.Trigger trigger = createValidTrigger("0 0 12 * * @ #"); // 包含无效字符
  229 + public void testMatches_invalidCharactersCron() {
  230 + // 准备参数
  231 + IotDeviceMessage message = createDeviceMessage();
  232 + String cronExpression = "0 0 12 * * @ #"; // 包含无效字符的 cron 表达式
  233 + IotSceneRuleDO.Trigger trigger = createValidTrigger(cronExpression);
208 234  
209   - // when
210   - boolean result = matcher.isMatched(message, trigger);
  235 + // 调用
  236 + boolean result = matcher.matches(message, trigger);
211 237  
212   - // then
  238 + // 断言
213 239 assertFalse(result);
214 240 }
215 241  
216 242 @Test
217   - public void testIsMatched_Success_RangeCron() {
218   - // given
219   - IotDeviceMessage message = new IotDeviceMessage();
  243 + public void testMatches_rangeCronSuccess() {
  244 + // 准备参数
  245 + IotDeviceMessage message = createDeviceMessage();
220 246 IotSceneRuleDO.Trigger trigger = createValidTrigger("0 0 9-17 * * MON-FRI"); // 工作日9-17点
221 247  
222   - // when
223   - boolean result = matcher.isMatched(message, trigger);
  248 + // 调用
  249 + boolean result = matcher.matches(message, trigger);
224 250  
225   - // then
  251 + // 断言
226 252 assertTrue(result);
227 253 }
228 254  
229 255 // ========== 辅助方法 ==========
230 256  
231 257 /**
  258 + * 创建设备消息
  259 + */
  260 + private IotDeviceMessage createDeviceMessage() {
  261 + IotDeviceMessage message = new IotDeviceMessage();
  262 + message.setDeviceId(randomLongId());
  263 + return message;
  264 + }
  265 +
  266 + /**
232 267 * 创建有效的定时触发器
233 268 */
234 269 private IotSceneRuleDO.Trigger createValidTrigger(String cronExpression) {
... ... @@ -237,4 +272,5 @@ public class TimerTriggerMatcherTest extends BaseMockitoUnitTest {
237 272 trigger.setCronExpression(cronExpression);
238 273 return trigger;
239 274 }
  275 +
240 276 }
... ...