Commit 21945e6b1e381e0138bf553dfe75384beac89d7c
Committed by
Gitee
!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 | } | ... | ... |