2026-06-24 f4bd1f3c89d906131495a0aca5aaf82966378510
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package cn.iocoder.yudao.module.iot.service.rule.action.databridge;
 
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
import cn.iocoder.yudao.module.iot.core.mq.message.IotDeviceMessage;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.IotDataSinkDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.rule.config.*;
import cn.iocoder.yudao.module.iot.service.rule.data.action.*;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
 
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
 
/**
 * {@link IotDataRuleAction} 实现类的单元测试
 *
 * @author HUIHUI
 */
@Disabled // 默认禁用,需要手动启用测试
@Slf4j
public class IotDataBridgeExecuteTest extends BaseMockitoUnitTest {
 
    private IotDeviceMessage message;
 
    @Mock
    private RestTemplate restTemplate;
 
    @InjectMocks
    private IotHttpDataSinkAction httpDataBridgeExecute;
 
    @BeforeEach
    public void setUp() {
        // TODO @芋艿:@puhui999:需要调整下;
        // 创建共享的测试消息
        //message = IotDeviceMessage.builder().messageId("TEST-001").reportTime(LocalDateTime.now())
        //        .productKey("testProduct").deviceName("testDevice")
        //        .type("property").identifier("temperature").data("{\"value\": 60}")
        //        .build();
    }
 
    @Test
    public void testKafkaMQDataBridge() throws Exception {
        // 1. 创建执行器实例
        IotKafkaDataRuleAction action = new IotKafkaDataRuleAction();
 
        // 2. 创建配置
        IotDataSinkKafkaConfig config = new IotDataSinkKafkaConfig()
                .setBootstrapServers("127.0.0.1:9092")
                .setTopic("test-topic")
                .setSsl(false)
                .setUsername(null)
                .setPassword(null);
 
        // 3. 执行测试并验证缓存
        executeAndVerifyCache(action, config, "KafkaMQ");
    }
 
    @Test
    public void testRabbitMQDataBridge() throws Exception {
        // 1. 创建执行器实例
        IotRabbitMQDataRuleAction action = new IotRabbitMQDataRuleAction();
 
        // 2. 创建配置
        IotDataSinkRabbitMQConfig config = new IotDataSinkRabbitMQConfig()
                .setHost("localhost")
                .setPort(5672)
                .setVirtualHost("/")
                .setUsername("admin")
                .setPassword("123456")
                .setExchange("test-exchange")
                .setRoutingKey("test-key")
                .setQueue("test-queue");
 
        // 3. 执行测试并验证缓存
        executeAndVerifyCache(action, config, "RabbitMQ");
    }
 
    @Test
    public void testRedisDataBridge() throws Exception {
        // 1. 创建执行器实例
        IotRedisRuleAction action = new IotRedisRuleAction();
 
        // 2. 创建配置 - 测试 Stream 数据结构
        IotDataSinkRedisConfig config = new IotDataSinkRedisConfig();
        config.setHost("127.0.0.1");
        config.setPort(6379);
        config.setDatabase(0);
        config.setPassword("123456");
        config.setTopic("test-stream");
        config.setDataStructure(1); // Stream 类型
 
        // 3. 执行测试并验证缓存
        executeAndVerifyCache(action, config, "Redis");
    }
 
    @Test
    public void testRocketMQDataBridge() throws Exception {
        // 1. 创建执行器实例
        IotRocketMQDataRuleAction action = new IotRocketMQDataRuleAction();
 
        // 2. 创建配置
        IotDataSinkRocketMQConfig config = new IotDataSinkRocketMQConfig()
                .setNameServer("127.0.0.1:9876")
                .setGroup("test-group")
                .setTopic("test-topic")
                .setTags("test-tag");
 
        // 3. 执行测试并验证缓存
        executeAndVerifyCache(action, config, "RocketMQ");
    }
 
    @Test
    public void testHttpDataBridge() throws Exception {
        // 1. 配置 RestTemplate mock 返回成功响应
        when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(), any(Class.class)))
                .thenReturn(new ResponseEntity<>("Success", HttpStatus.OK));
 
        // 2. 创建配置
        IotDataSinkHttpConfig config = new IotDataSinkHttpConfig()
                .setUrl("https://doc.iocoder.cn/").setMethod(HttpMethod.GET.name());
 
        // 3. 执行测试
        log.info("[testHttpDataBridge][执行HTTP数据桥接测试]");
        httpDataBridgeExecute.execute(message, new IotDataSinkDO()
                .setType(httpDataBridgeExecute.getType()).setConfig(config));
    }
 
    /**
     * 执行测试并验证缓存的通用方法
     *
     * @param action 执行器实例
     * @param config 配置对象
     * @param type MQ 类型
     * @throws Exception 如果执行过程中发生异常
     */
    private void executeAndVerifyCache(IotDataRuleAction action, IotAbstractDataSinkConfig config, String type)
            throws Exception {
        log.info("[test{}DataBridge][第一次执行,应该会创建新的 producer]", type);
        action.execute(message, new IotDataSinkDO().setType(action.getType()).setConfig(config));
 
        log.info("[test{}DataBridge][第二次执行,应该会复用缓存的 producer]", type);
        action.execute(message, new IotDataSinkDO().setType(action.getType()).setConfig(config));
    }
 
}