googletest:sample3分析

news/2025/2/27 18:27:25/文章来源:https://www.cnblogs.com/fortunely/p/18741407

目录
  • 待测文件
  • 测试文件
  • 小结

待测文件

sample3通过一个链表实现了一个队列(Queue)功能,队列的每个节点都是一个QueueNode对象. 链表没有虚拟头节点,head_指向头节点,last_指向尾节点.

对于Queue类,实现了:

  • 构造、析构;
  • 插入元素(Enqueue)到队列末尾,从队列头弹出(Dequeue)元素;
  • 队列数据清除(Clear);
  • 队列大小的访问(Size);
  • 队列头元节点的访问(Head),尾节点的访问(Last);
  • 构造一个新的队列(Map),与原队列的每个元素作为方法的参数,方法调用结果作为新队列元素逐个插入.

对于QueueNode类,实现了:

  • 模板类型的元素值;
  • 指向下一个节点的指针.

"-inl" 表明这是个声明和实现的混合文件.

sample3-inl.h

#include <stddef.h>// Queue is a simple queue implemented as a singled-linked list.
//
// The element type must support copy constructor.
template <typename E>  // E is the element type
class Queue;// QueueNode is a node in a Queue, which consists of an element of
// type E and a pointer to the next node.
template <typename E>  // E is the element type
class QueueNode {friend class Queue<E>;public:// Gets the element in this node.const E& element() const { return element_; }// Gets the next node in the queue.QueueNode* next() { return next_; }const QueueNode* next() const { return next_; }private:// Creates a node with a given element value.  The next pointer is// set to NULL.explicit QueueNode(const E& an_element): element_(an_element), next_(nullptr) {}// We disable the default assignment operator and copy c'tor.const QueueNode& operator=(const QueueNode&);QueueNode(const QueueNode&);E element_;QueueNode* next_;
};template <typename E>  // E is the element type.
class Queue {public:// Creates an empty queue.Queue() : head_(nullptr), last_(nullptr), size_(0) {}// D'tor.  Clears the queue.~Queue() { Clear(); }// Clears the queue.void Clear() {if (size_ > 0) {// 1. Deletes every node.QueueNode<E>* node = head_;QueueNode<E>* next = node->next();for (;;) {delete node;node = next;if (node == nullptr) break;next = node->next();}// 2. Resets the member variables.head_ = last_ = nullptr;size_ = 0;}}// Gets the number of elements.size_t Size() const { return size_; }// Gets the first element of the queue, or NULL if the queue is empty.QueueNode<E>* Head() { return head_; }const QueueNode<E>* Head() const { return head_; }// Gets the last element of the queue, or NULL if the queue is empty.QueueNode<E>* Last() { return last_; }const QueueNode<E>* Last() const { return last_; }// Adds an element to the end of the queue.  A copy of the element is// created using the copy constructor, and then stored in the queue.// Changes made to the element in the queue doesn't affect the source// object, and vice versa.void Enqueue(const E& element) {QueueNode<E>* new_node = new QueueNode<E>(element);if (size_ == 0) {head_ = last_ = new_node;size_ = 1;} else {last_->next_ = new_node;last_ = new_node;size_++;}}// Removes the head of the queue and returns it.  Returns NULL if// the queue is empty.E* Dequeue() {if (size_ == 0) {return nullptr;}const QueueNode<E>* const old_head = head_;head_ = head_->next_;size_--;if (size_ == 0) {last_ = nullptr;}E* element = new E(old_head->element());delete old_head;return element;}// Applies a function/functor on each element of the queue, and// returns the result in a new queue.  The original queue is not// affected.template <typename F>Queue* Map(F function) const {Queue* new_queue = new Queue();for (const QueueNode<E>* node = head_; node != nullptr;node = node->next_) {new_queue->Enqueue(function(node->element()));}return new_queue;}private:QueueNode<E>* head_;  // The first node of the queue.QueueNode<E>* last_;  // The last node of the queue.size_t size_;         // The number of elements in the queue.// We disallow copying a queue.Queue(const Queue&);const Queue& operator=(const Queue&);
};

测试文件

sample3_unittest.cc

#include "sample3-inl.h"
#include "gtest/gtest.h"
namespace {
// To use a test fixture, derive a class from testing::Test.
class QueueTestSmpl3 : public testing::Test {protected:  // You should make the members protected s.t. they can be// accessed from sub-classes.// virtual void SetUp() will be called before each test is run.  You// should define it if you need to initialize the variables.// Otherwise, this can be skipped.void SetUp() override {q1_.Enqueue(1);q2_.Enqueue(2);q2_.Enqueue(3);}// virtual void TearDown() will be called after each test is run.// You should define it if there is cleanup work to do.  Otherwise,// you don't have to provide it.//// virtual void TearDown() {// }// A helper function that some test uses.static int Double(int n) { return 2 * n; }// A helper function for testing Queue::Map().void MapTester(const Queue<int>* q) {// Creates a new queue, where each element is twice as big as the// corresponding one in q.const Queue<int>* const new_q = q->Map(Double);// Verifies that the new queue has the same size as q.ASSERT_EQ(q->Size(), new_q->Size());// Verifies the relationship between the elements of the two queues.for (const QueueNode<int>*n1 = q->Head(), *n2 = new_q->Head();n1 != nullptr; n1 = n1->next(), n2 = n2->next()) {EXPECT_EQ(2 * n1->element(), n2->element());}delete new_q;}// Declares the variables your tests want to use.Queue<int> q0_;Queue<int> q1_;Queue<int> q2_;
};// When you have a test fixture, you define a test using TEST_F
// instead of TEST.// Tests the default c'tor.
TEST_F(QueueTestSmpl3, DefaultConstructor) {// You can access data in the test fixture here.EXPECT_EQ(0u, q0_.Size());
}// Tests Dequeue().
TEST_F(QueueTestSmpl3, Dequeue) {int* n = q0_.Dequeue();EXPECT_TRUE(n == nullptr);n = q1_.Dequeue();ASSERT_TRUE(n != nullptr);EXPECT_EQ(1, *n);EXPECT_EQ(0u, q1_.Size());delete n;n = q2_.Dequeue();ASSERT_TRUE(n != nullptr);EXPECT_EQ(2, *n);EXPECT_EQ(1u, q2_.Size());delete n;
}// Tests the Queue::Map() function.
TEST_F(QueueTestSmpl3, Map) {MapTester(&q0_);MapTester(&q1_);MapTester(&q2_);
}
}  // namespace

sample3的测试并没有像sample2那样,在测试用例中定义测试对象,然后进行一系列操作后再断言测试,而是用了一个集成自testing::Test的测试夹具类QueueTestSmpl3,包装了对测试对象的一系列操作,后续测试不需要重复编写.

TEST_IF:用测试夹具测试时,定义测试用例不用TEST,而是用TEST_IF.
ASSERT_TRUE:功能类似EXPECT_TRUE,但断言不通过时,前者会导致测试不会继续,后者会继续.

对于QueueTestSmpl3类,

  • 定义了3个待测的Queue<int>对象q0_, q1_, q2_,并用父类testing::Test的派生方法进行初始化;
  • Setup():派生自testing::Test,会在执行测试用例之前运行. 如果有数据初始化工作,可以在这里进行;
  • MapTester():包装对Queue::Map()的测试操作.

对于QueueQueueNode,并没有对每个public方法设计测试用例,而是让测试用例覆盖其成员方法.

  • DefaultConstructor:测试默认构造函数,包含了ctor和Enqueue();
  • Dequeue:测试出队列方法;
  • Map:利用测试夹具中定义的MapTester方法,对Queue::Map进行测试.

当然,这里其实没有覆盖对Queue::Clear()方法的测试.

小结

利用测试夹具类(继承自testing::test)封装对待测类对象的初始化,可自定义测试方法 封装对待测对象的一系列操作.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/890750.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[MoE] Deepseek的All-to-all通信: DeepEP代码解读

[MoE] Deepseek的All-to-all通信: DeepEP代码解读 前言 最近,Deepseek开源了一系列MoE的优化技术,让我们看到了AI infra的强大之处。其中,第二天发布的DeepEP则是针对MoE中EP的all-to-all通信进行了优化。 我最近也在关注MoE和all-to-all,之前的MoE普遍使用NCCL的p2p通信进…

Java泛型上下界

有如下类的继承关系 // okFruit apple = new Apple(); List<Fruit> plate = new ArrayList<Apple>(); 它会在Idea里报红线,运行会报错:java: 不兼容的类型: java.util.ArrayList<Apple>无法转换为java.util.List<Fruit>,显然在集合间不存在继承引用…

Redis复习-通信协议、内存回收

通信协议 RESP协议 Redis是一个CS架构的软件,通信一般分两步(不包括pipeline和PubSub): 1.客户端(client)向服务端(server)发送一条命令 2.服务端解析并执行命令,返回响应结果给客户端 因此客户端发送命令的格式、服务端响应结果的格式必须有一个规范,这个规范就是通…

vi和vim快捷键

vi和vim常用的一些快捷键分类 快捷键 说明模式切换 i 进入插入模式(在光标前插入文本)。a 进入插入模式(在光标后插入文本)。o 在当前行下方插入新行并进入插入模式。O 在当前行上方插入新行并进入插入模式。Esc 退出插入模式,返回命令模式。: 进入命令模式(用于输入命令…

Go红队开发—语法补充

之前有师傅问这个系列好像跟红队没啥关系,前几期确实没啥关系,因为这都是进行红队工具开发的前置知识点,对于我个人强迫症而言只是想让这个系列更加完善而已,所以前置知识也加进去了,有GO只是的大佬可以等下一期哈!感谢支持。目录错误控制使用自定义错误类型错误包装erro…

Security认证失败逻辑

通过一系列的过滤器最终走到 FilterSecurityInterceptor package org.springframework.security.access.vote;public class AffirmativeBased extends AbstractAccessDecisionManager {public AffirmativeBased(List<AccessDecisionVoter<? extends Object>> deci…

关于书店管理系统的二次开发

一、来源 来自同学期末大作业。实现了基本的书店业务功能,包括书本信息管理、客户信息管理、购物车操作以及订单生成与保存等。 二、运行环境 + 运行结果的截图 操作系统:Windows 11 开发工具:Visual Studio 2022// BookStore.h点击查看代码 #ifndef BOOKSTORE_H #define BO…

CNC数控机床运行状态参数采集联网 对接软件MES 系统

IP 端口 TCP端口 流程任务 当前位置或者目标位置及描述 状态 需要接口内容 请求地址-AGV 请求AGV参数 请求AGV返回信息 PLC-地址 写入PLC值 读取PLC值 EDM-地址 写入EDM值 读取EDM值进入上下料进程 进入EDM上料台动作-动作 即将进入EDM上料台 "1.达…

Redis+Docker集群部署

机器故障了怎么办? Redis 是内存数据库,我们知道可以通过持久化机制,保存快照或者保存记录日志的方式,将数据持久化到磁盘。但是,如果机器故障了或磁盘坏了,数据就不就全没了吗?这种情况应该怎么办呢?别担心,考虑主从模式。 主从模式 给主节点 Master 配置一个从节点 …

【T20天正电气V10.0软件下载与安装教程】

1、安装包 扫描下方二维码关注「软知社」,后台回复【024】三位数字即可免费获取分享链接,无广告拒绝套路; 2、安装教程双击T20天正电气V10.0安装包,弹窗安装对话框选择我接收,点击下一步选择安装位置,点击下一步点击下一步等待安装进度完成安装完成,点击完成按钮点击下…

windows底层激活破解一步到位,TSforge也太暴力了!

windows底层激活破解一步到位,TSforge也太暴力了! windows底层激活破解一步到位,TSforge也太暴力了! 微软系统一直是需要收费的,也是电脑用户们经常遇到的问题,市面上也有很多工具, 但是今天的工具是最新的且**呼声最高、最彻底的**,需要的话赶紧保存下来,实际使用只需…

No.23 CSS--定位

一、定义position属性指定了元素的定位类型。其中,绝对定位和固定定位会脱离文档流. 设置定位之后:可以使用四个方向值进行调整位置:Ieft、top、right、bottom.二、相对定位<head><meta charset="UTF-8"><meta name="viewport" content=&q…