🍃前言
本次开发任务:对MemoryDataCenter(管理内存数据) 进行功能测试
🌳测试准备
创建两个方法,分别在每个测试单元前执行与每个单元后执行
测试单元前,创建一个 MemoryDataCenter 的对象
测试单元后,将这个对象置为 null
代码执行如下:
private MemoryDataCenter memoryDataCenter = null; @BeforeEach public void setUp() { memoryDataCenter = new MemoryDataCenter(); } @AfterEach public void tearDown() { memoryDataCenter = null; }
🎋测试交换机与队列
首先为了测试,我们的创建交换机与队列
其次再进行测试,测试步骤都分为四步
- 构造一个交换机/队列插入内存中
- 查询出这个交换机/对列, 比较结果是否一致. 此处直接比较这俩引用指向同一个对象
- 删除这个交换机/队列
- 再次查询,看是否已经查不到了
需要注意的时:
- 我们再判断是否为null用的是:
Assertions.assertNull()
代码实现如下:
// 创建一个测试交换机 private Exchange createTestExchange(String exchangeName) { Exchange exchange = new Exchange(); exchange.setName(exchangeName); exchange.setType(ExchangeType.DIRECT); exchange.setAutoDelete(false); exchange.setDurable(true); return exchange; } // 创建一个测试队列 private MSGQueue createTestQueue(String queueName) { MSGQueue queue = new MSGQueue(); queue.setName(queueName); queue.setDurable(true); queue.setExclusive(false); queue.setAutoDelete(false); return queue; } // 针对交换机进行测试 @Test public void testExchange() { // 1. 先构造一个交换机并插入. Exchange expectedExchange = createTestExchange("testExchange"); memoryDataCenter.insertExchange(expectedExchange); // 2. 查询出这个交换机, 比较结果是否一致. 此处直接比较这俩引用指向同一个对象. Exchange actualExchange = memoryDataCenter.getExchange("testExchange"); Assertions.assertEquals(expectedExchange, actualExchange); // 3. 删除这个交换机 memoryDataCenter.deleteExchange("testExchange"); // 4. 再查一次, 看是否就查不到了 actualExchange = memoryDataCenter.getExchange("testExchange"); Assertions.assertNull(actualExchange); } // 针对队列进行测试 @Test public void testQueue() { // 1. 构造一个队列, 并插入 MSGQueue expectedQueue = createTestQueue("testQueue"); memoryDataCenter.insertQueue(expectedQueue); // 2. 查询这个队列, 并比较 MSGQueue actualQueue = memoryDataCenter.getQueue("testQueue"); Assertions.assertEquals(expectedQueue, actualQueue); // 3. 删除这个队列 memoryDataCenter.deleteQueue("testQueue"); // 4. 再次查询队列, 看是否能查到 actualQueue = memoryDataCenter.getQueue("testQueue"); Assertions.assertNull(actualQueue); }
🎍测试绑定
首先我们构造一个绑定对象
然后添加该绑定对象
获取绑定对象时,我们需要注意的是:我们书写过两个获取绑定对象的方法
- 一个是通过交换机的名字与队列名字查找的唯一绑定
- 一个是通过交换机的名字返回所有绑定
关于唯一绑定,只需要查询,然后比对是否为统一对象即可
关于所有哦绑定,我们还需要多做的判断是:我们获取的链表的长度是否为1
删除相应绑定后,我们只需要判断是否已经null即可
代码实现如下:
// 针对绑定进行测试 @Test public void testBinding() throws MqException { Binding expectedBinding = new Binding(); expectedBinding.setExchangeName("testExchange"); expectedBinding.setQueueName("testQueue"); expectedBinding.setBindingKey("testBindingKey"); memoryDataCenter.insertBinding(expectedBinding); Binding actualBinding = memoryDataCenter.getBinding("testExchange", "testQueue"); Assertions.assertEquals(expectedBinding, actualBinding); ConcurrentHashMap<String, Binding> bindingMap = memoryDataCenter.getBindings("testExchange"); Assertions.assertEquals(1, bindingMap.size()); Assertions.assertEquals(expectedBinding, bindingMap.get("testQueue")); memoryDataCenter.deleteBinding(expectedBinding); actualBinding = memoryDataCenter.getBinding("testExchange", "testQueue"); Assertions.assertNull(actualBinding); }
🍀测试总消息
在前面存储消息是,我们有两种存储结构,
- 一种是key:消息ID ,value:消息对象
- 一种是key:消息ID, value:装有消息对象的链表
这次我们先来测试前一种
首相我们准备一个创建消息的方法,用来构造消息
然后测试步骤依旧分为四步:
- 添加消息
- 取出消息
- 对比消息对象是否为同一个
- 删除消息后查看是否为 null
代码实现如下:
private Message createTestMessage(String content) { Message message = Message.createMessageWithId("testRoutingKey", null, content.getBytes()); return message; } @Test public void testMessage() { Message expectedMessage = createTestMessage("testMessage"); memoryDataCenter.addMessage(expectedMessage); Message actualMessage = memoryDataCenter.getMessage(expectedMessage.getMessageId()); Assertions.assertEquals(expectedMessage, actualMessage); memoryDataCenter.removeMessage(expectedMessage.getMessageId()); actualMessage = memoryDataCenter.getMessage(expectedMessage.getMessageId()); Assertions.assertNull(actualMessage); }
🎄测试消息链表
测试步骤分为以下三步:
- 创建一个队列, 创建 10 条消息, 把这些消息都插入队列中.
- 从队列中取出这些消息
- 比较取出的消息和之前的消息是否一致
代码实现如下:
@Test public void testSendMessage() { // 1. 创建一个队列, 创建 10 条消息, 把这些消息都插入队列中. MSGQueue queue = createTestQueue("testQueue"); List<Message> expectedMessages = new ArrayList<>(); for (int i = 0; i < 10; i++) { Message message = createTestMessage("testMessage" + i); memoryDataCenter.sendMessage(queue, message); expectedMessages.add(message); } // 2. 从队列中取出这些消息. List<Message> actualMessages = new ArrayList<>(); while (true) { Message message = memoryDataCenter.pollMessage("testQueue"); if (message == null) { break; } actualMessages.add(message); } // 3. 比较取出的消息和之前的消息是否一致. Assertions.assertEquals(expectedMessages.size(), actualMessages.size()); for (int i = 0; i < expectedMessages.size(); i++) { Assertions.assertEquals(expectedMessages.get(i), actualMessages.get(i)); } }
🌴测试待确认消息
测试步骤分为四步走
- 添加未确认消息
- 取出消息
- 判断消息是否为同一对象
- 删除后判定是否null
代码实现如下:
@Test public void testMessageWaitAck() { Message expectedMessage = createTestMessage("expectedMessage"); memoryDataCenter.addMessageWaitAck("testQueue", expectedMessage); Message actualMessage = memoryDataCenter.getMessageWaitAck("testQueue", expectedMessage.getMessageId()); Assertions.assertEquals(expectedMessage, actualMessage); memoryDataCenter.removeMessageWaitAck("testQueue", expectedMessage.getMessageId()); actualMessage = memoryDataCenter.getMessageWaitAck("testQueue", expectedMessage.getMessageId()); Assertions.assertNull(actualMessage); }
🌲从硬盘上读取数据
从硬盘上读取数据,首先我们要构造硬盘上的数据。
而且由于我们构造这些数据时,会涉及到数据库操作,, 依赖 MyBatis. 就需要先启动 SpringApplication, 这样才能进行后续的数据库操作.
然后先在硬盘上构造好数据,然后再构造交换机、队列、绑定、消息
接下来进行结果的比对
最后清理硬盘的数据, 把整个 data 目录里的内容都删掉(包含了 meta.db 和 队列的目录).
实现代码如下:
@Test public void testRecovery() throws IOException, MqException, ClassNotFoundException { // 由于后续需要进行数据库操作, 依赖 MyBatis. 就需要先启动 SpringApplication, 这样才能进行后续的数据库操作. MqApplication.context = SpringApplication.run(MqApplication.class); // 1. 在硬盘上构造好数据 DiskDataCenter diskDataCenter = new DiskDataCenter(); diskDataCenter.init(); // 构造交换机 Exchange expectedExchange = createTestExchange("testExchange"); diskDataCenter.insertExchange(expectedExchange); // 构造队列 MSGQueue expectedQueue = createTestQueue("testQueue"); diskDataCenter.insertQueue(expectedQueue); // 构造绑定 Binding expectedBinding = new Binding(); expectedBinding.setExchangeName("testExchange"); expectedBinding.setQueueName("testQueue"); expectedBinding.setBindingKey("testBindingKey"); diskDataCenter.insertBinding(expectedBinding); // 构造消息 Message expectedMessage = createTestMessage("testContent"); diskDataCenter.sendMessage(expectedQueue, expectedMessage); // 2. 执行恢复操作 memoryDataCenter.recovery(diskDataCenter); // 3. 对比结果 Exchange actualExchange = memoryDataCenter.getExchange("testExchange"); Assertions.assertEquals(expectedExchange.getName(), actualExchange.getName()); Assertions.assertEquals(expectedExchange.getType(), actualExchange.getType()); Assertions.assertEquals(expectedExchange.isDurable(), actualExchange.isDurable()); Assertions.assertEquals(expectedExchange.isAutoDelete(), actualExchange.isAutoDelete()); MSGQueue actualQueue = memoryDataCenter.getQueue("testQueue"); Assertions.assertEquals(expectedQueue.getName(), actualQueue.getName()); Assertions.assertEquals(expectedQueue.isDurable(), actualQueue.isDurable()); Assertions.assertEquals(expectedQueue.isAutoDelete(), actualQueue.isAutoDelete()); Assertions.assertEquals(expectedQueue.isExclusive(), actualQueue.isExclusive()); Binding actualBinding = memoryDataCenter.getBinding("testExchange", "testQueue"); Assertions.assertEquals(expectedBinding.getExchangeName(), actualBinding.getExchangeName()); Assertions.assertEquals(expectedBinding.getQueueName(), actualBinding.getQueueName()); Assertions.assertEquals(expectedBinding.getBindingKey(), actualBinding.getBindingKey()); Message actualMessage = memoryDataCenter.pollMessage("testQueue"); Assertions.assertEquals(expectedMessage.getMessageId(), actualMessage.getMessageId()); Assertions.assertEquals(expectedMessage.getRoutingKey(), actualMessage.getRoutingKey()); Assertions.assertEquals(expectedMessage.getDeliverMode(), actualMessage.getDeliverMode()); Assertions.assertArrayEquals(expectedMessage.getBody(), actualMessage.getBody()); // 4. 清理硬盘的数据, 把整个 data 目录里的内容都删掉(包含了 meta.db 和 队列的目录). MqApplication.context.close(); File dataDir = new File("./data"); FileUtils.deleteDirectory(dataDir); }
⭕总结
关于《【消息队列开发】 实现MemoryDataCenterTests类——测试管理内存数据》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下