【消息队列开发】实现DataBaseManagerTests(测试单元)

简介: 【消息队列开发】实现DataBaseManagerTests(测试单元)

🍃前言

今天我们来对前面所开发的数据库操作的功能进行测试一下

🌳准备工作

由于我们接下来要写很多测试用例

并且我们希望每个方法都是一个/一组单元测试用例,互不干扰

所以我们还做一些准备工作,需要写两个方法, 分别用于进行 “准备工作” 和 “收尾工作”

这里我们使用注解的方式进行实现

添加@BeforeEach,表示每个测试单元开始前都要执行该方法

在这个方法里我们需要做的事情有:

  • 调用 init 方法进行建库建表
  • 但是由于我们的 init 方法是手动获取bean对象的,需要依赖context ,所以我们这里要先把context对象先搞出来

实现代码如下:

// 使用这个方法, 来执行准备工作. 每个用例执行前, 都要调用这个方法.
@BeforeEach
public void setUp() {
    // 由于在 init 中, 需要通过 context 对象拿到 metaMapper 实例的.
    // 所以就需要先把 context 对象给搞出来.
    MqApplication.context = SpringApplication.run(MqApplication.class);
    dataBaseManager.init();
}

使用@AfterEach来进行收尾工作

此处我们要做的工作有:

  • 这里要进行的操作, 就是把数据库给清空~~ (把数据库文件,meta.db 直接删了就行了)
  • 但是,请注意, 此处不能直接就删除, 而需要先关闭上述 context 对象
  • 而此处的 context 对象, 持有了 MetaMapper 的实例,MetaMapper 实例又打开了 meta.db 数据库文件.
  • 如果 meta.db 被别人打开了, 此时的删除文件操作是不会成功的 (Windows 系统的限制, Linux 则没这个问题).
  • 另一方面, 获取 context 操作, 会占用 8080 端口. 此处的 close 也是释放 8080.

所以我们需要进行关闭context对象之后,再进行删除删表操作

代码实现如下:

@AfterEach
    public void tearDown() {
        // 这里要进行的操作, 就是把数据库给清空~~ (把数据库文件, meta.db 直接删了就行了)
        // 注意, 此处不能直接就删除, 而需要先关闭上述 context 对象!!
        // 此处的 context 对象, 持有了 MetaMapper 的实例, MetaMapper 实例又打开了 meta.db 数据库文件.
        // 如果 meta.db 被别人打开了, 此时的删除文件操作是不会成功的 (Windows 系统的限制, Linux 则没这个问题).
        // 另一方面, 获取 context 操作, 会占用 8080 端口. 此处的 close 也是释放 8080.
        MqApplication.context.close();
        dataBaseManager.deleteDB();
    }

🎍书写测试代码

这里的测试代码逻辑简单,一一进行测试就好,这里我就不进行讲解

这里有一点需要注意的是,我们在观察结果的时候,我们可以使用打印到控制台的方式进行观察,但是这样难免不准确或不易观察

这里我们使用断言操作进行判断,使用方法如下:

Assertions.assertEquals(expected, actual);

我们只需要在这里面添加我们所需要比对的参数就好,那个在前那个在后不重要

  • 但是 assertEquals 的形参, 第一个形参叫做 expected (预期的), 第二个形参叫做 actual (实际的)

具体使用看个人习惯

需要注意的是:

  • 正确使用断言后,如果测试代码没有出现问题,说明测试通过
  • 如果预期值与实际值不符合,就会进行报错,如下图所示

如此一来我们便可以进行测试了

测试代码如下;

@Test
public void testInitTable() {
    // 由于 init 方法, 已经在上面 setUp 中调用过了. 直接在测试用例代码中, 检查当前的数据库状态即可.
    // 直接从数据库中查询. 看数据是否符合预期.
    // 查交换机表, 里面应该有一个数据(匿名的 exchange); 查队列表, 没有数据; 查绑定表, 没有数据.
    List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();
    List<MSGQueue> queueList = dataBaseManager.selectAllQueues();
    List<Binding> bindingList = dataBaseManager.selectAllBindings();
    // 直接打印结果, 通过肉眼来检查结果, 固然也可以. 但是不优雅, 不方便.
    // 更好的办法是使用断言.
    // System.out.println(exchangeList.size());
    // assertEquals 判定结果是不是相等.
    // 注意这俩参数的顺序. 虽然比较相等, 谁在前谁在后, 无所谓.
    // 但是 assertEquals 的形参, 第一个形参叫做 expected (预期的), 第二个形参叫做 actual (实际的)
    Assertions.assertEquals(1, exchangeList.size());
    Assertions.assertEquals("", exchangeList.get(0).getName());
    Assertions.assertEquals(ExchangeType.DIRECT, exchangeList.get(0).getType());
    Assertions.assertEquals(0, queueList.size());
    Assertions.assertEquals(0, bindingList.size());
}
private Exchange createTestExchange(String exchangeName) {
    Exchange exchange = new Exchange();
    exchange.setName(exchangeName);
    exchange.setType(ExchangeType.FANOUT);
    exchange.setAutoDelete(false);
    exchange.setDurable(true);
    exchange.setArguments("aaa", 1);
    exchange.setArguments("bbb", 2);
    return exchange;
}
@Test
public void testInsertExchange() {
    // 构造一个 Exchange 对象, 插入到数据库中. 再查询出来, 看结果是否符合预期.
    Exchange exchange = createTestExchange("testExchange");
    dataBaseManager.insertExchange(exchange);
    // 插入完毕之后, 查询结果
    List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();
    Assertions.assertEquals(2, exchangeList.size());
    Exchange newExchange = exchangeList.get(1);
    Assertions.assertEquals("testExchange", newExchange.getName());
    Assertions.assertEquals(ExchangeType.FANOUT, newExchange.getType());
    Assertions.assertEquals(false, newExchange.isAutoDelete());
    Assertions.assertEquals(true, newExchange.isDurable());
    Assertions.assertEquals(1, newExchange.getArguments("aaa"));
    Assertions.assertEquals(2, newExchange.getArguments("bbb"));
}
@Test
public void testDeleteExchange() {
    // 先构造一个交换机, 插入数据库; 然后再按照名字删除即可!
    Exchange exchange = createTestExchange("testExchange");
    dataBaseManager.insertExchange(exchange);
    List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();
    Assertions.assertEquals(2, exchangeList.size());
    Assertions.assertEquals("testExchange", exchangeList.get(1).getName());
    // 进行删除操作
    dataBaseManager.deleteExchange("testExchange");
    // 再次查询
    exchangeList = dataBaseManager.selectAllExchanges();
    Assertions.assertEquals(1, exchangeList.size());
    Assertions.assertEquals("", exchangeList.get(0).getName());
}
private MSGQueue createTestQueue(String queueName) {
    MSGQueue queue = new MSGQueue();
    queue.setName(queueName);
    queue.setDurable(true);
    queue.setAutoDelete(false);
    queue.setExclusive(false);
    queue.setArguments("aaa", 1);
    queue.setArguments("bbb", 2);
    return queue;
}
@Test
public void testInsertQueue() {
    //构造队列对象
    MSGQueue queue = createTestQueue("testQueue");
    dataBaseManager.insertQueue(queue);
    List<MSGQueue> queueList = dataBaseManager.selectAllQueues();
    Assertions.assertEquals(1, queueList.size());
    MSGQueue newQueue = queueList.get(0);
    Assertions.assertEquals("testQueue", newQueue.getName());
    Assertions.assertEquals(true, newQueue.isDurable());
    Assertions.assertEquals(false, newQueue.isAutoDelete());
    Assertions.assertEquals(false, newQueue.isExclusive());
    Assertions.assertEquals(1, newQueue.getArguments("aaa"));
    Assertions.assertEquals(2, newQueue.getArguments("bbb"));
}
@Test
public void testDeleteQueue() {
    MSGQueue queue = createTestQueue("testQueue");
    dataBaseManager.insertQueue(queue);
    List<MSGQueue> queueList = dataBaseManager.selectAllQueues();
    Assertions.assertEquals(1, queueList.size());
    // 进行删除
    dataBaseManager.deleteQueue("testQueue");
    queueList = dataBaseManager.selectAllQueues();
    Assertions.assertEquals(0, queueList.size());
}
private Binding createTestBinding(String exchangeName, String queueName) {
    Binding binding = new Binding();
    binding.setExchangeName(exchangeName);
    binding.setQueueName(queueName);
    binding.setBindingKey("testBindingKey");
    return binding;
}
@Test
public void testInsertBinding() {
    Binding binding = createTestBinding("testExchange", "testQueue");
    dataBaseManager.insertBinding(binding);
    List<Binding> bindingList = dataBaseManager.selectAllBindings();
    Assertions.assertEquals(1, bindingList.size());
    Assertions.assertEquals("testExchange", bindingList.get(0).getExchangeName());
    Assertions.assertEquals("testQueue", bindingList.get(0).getQueueName());
    Assertions.assertEquals("testBindingKey", bindingList.get(0).getBindingKey());
}
@Test
public void testDeleteBinding() {
    Binding binding = createTestBinding("testExchange", "testQueue");
    dataBaseManager.insertBinding(binding);
    List<Binding> bindingList = dataBaseManager.selectAllBindings();
    Assertions.assertEquals(1, bindingList.size());
    // 删除
    Binding toDeleteBinding = createTestBinding("testExchange", "testQueue");
    dataBaseManager.deleteBinding(toDeleteBinding);
    bindingList = dataBaseManager.selectAllBindings();
    Assertions.assertEquals(0, bindingList.size());
}

⭕总结

关于《【消息队列开发】实现DataBaseManagerTests(测试单元》就讲解到这儿,感谢大家的支持,欢迎各位留言交流以及批评指正,如果文章对您有帮助或者觉得作者写的还不错可以点一下关注,点赞,收藏支持一下!

相关文章
|
4月前
|
存储 测试技术 API
数据驱动开发软件测试脚本
今天刚提交了我的新作《带着ChatGPT玩转软件开发》给出版社,在写作期间跟着ChatGPT学到许多新知识。下面分享数据驱动开发软件测试脚本。
143 0
|
9月前
|
机器学习/深度学习 人工智能 并行计算
AI部署架构:A100、H100、A800、H800、H20的差异以及如何选型?开发、测试、生产环境如何进行AI大模型部署架构?
AI部署架构:A100、H100、A800、H800、H20的差异以及如何选型?开发、测试、生产环境如何进行AI大模型部署架构?
AI部署架构:A100、H100、A800、H800、H20的差异以及如何选型?开发、测试、生产环境如何进行AI大模型部署架构?
|
7月前
|
传感器 人工智能 JavaScript
鸿蒙开发:DevEcoTesting中的稳定性测试
DevEcoTesting主要的目的也是用于软件的测试,可以让开发者无需复杂的配置,即可一键执行测试任务,同时提供了测试报告和分析,无论是对于开发者还是测试同学来说,都是一个非常方便的工具。
270 3
鸿蒙开发:DevEcoTesting中的稳定性测试
|
6月前
|
敏捷开发 运维 数据可视化
DevOps看板工具中的协作功能:如何打破开发、测试与运维之间的沟通壁垒
在DevOps实践中,看板工具通过可视化任务管理和自动化流程,提升开发与运维团队的协作效率。它支持敏捷开发、持续交付,助力团队高效应对需求变化,实现跨职能协作与流程优化。
|
6月前
|
运维 jenkins 测试技术
"还在苦等开发部署环境?3步教你用Jenkins拿回测试主动权"
测试工程师最头疼的问题是什么?依赖开发部署环境! 开发延期→测试时间被压缩→紧急上线后BUG频出→测试背锅。传统流程中,测试被动等待部署,效率低下。而Jenkins自动化部署让测试人员自主搭建环境,实现: ✅ 随时触发测试,不再苦等开发 ✅ 部署效率提升10倍,抢回测试时间 ✅ 改善团队协作,减少互相甩锅 学习Jenkins部署能力,成为高效测试工程师,告别被动等待!
|
10月前
|
数据采集 算法 数据安全/隐私保护
【硬件测试】基于FPGA的4ASK调制解调通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文介绍了基于FPGA的4ASK调制解调系统的硬件测试版本,该系统包括testbench、高斯信道模块和误码率统计模块,并新增了ILA在线数据采集和VIO在线SNR设置功能。通过VIO设置不同SNR(如15dB和25dB),实现了对系统性能的实时监测与调整。4ASK是一种通过改变载波幅度表示数据的数字调制方式,适用于多种通信场景。FPGA平台的高效性和灵活性使其成为构建高性能通信系统的理想选择。
254 17
|
10月前
|
数据采集 算法 数据安全/隐私保护
【硬件测试】基于FPGA的4FSK调制解调通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
本文基于之前的文章《基于FPGA的4FSK调制解调系统》,增加了ILA在线数据采集模块和VIO在线SNR设置模块,实现了硬件测试版本。通过VIO设置不同SNR(如10dB和20dB),并展示了ILA采集的数据结果。四频移键控(4FSK)是一种数字调制方法,利用四个不同频率传输二进制数据,具有较高的频带利用率和抗干扰性能。输入的二进制数据分为两组,每组两个比特,对应四个频率f1、f2、f3、f4,分别代表二进制组合00、01、10、11。调制过程中选择相应频率输出,并进行幅度调制以增强抗干扰能力。接收端通过带通滤波器提取信号并还原为原始二进制数据。
267 7
|
消息中间件 C语言 RocketMQ
消息队列 MQ操作报错合集之出现"Connection reset by peer"的错误,该如何处理
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
消息中间件 Java C语言
消息队列 MQ使用问题之在使用C++客户端和GBase的ESQL进行编译时出现core dump,该怎么办
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
消息中间件 存储 Kafka
MQ 消息队列核心原理,12 条最全面总结!
本文总结了消息队列的12个核心原理,涵盖消息顺序性、ACK机制、持久化及高可用性等内容。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。