我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Go单元测试利器testify使用示例详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Go单元测试利器testify使用示例详解

testify

在团队里推行单元测试的时候,有一个反对的意见是:写单元测试耗时太多。且不论这个意见对错,单元测试确实不应该太费时间。这时候,一个好的单测辅助工具,显得格外重要。本文推荐的 testify(github.com/stretchr/te…) 包,具有断言、mock 等功能,能配合标准库,使你的单元测试更加简洁易读。

testify 有三个主要功能:

  • 断言,在 assert 包和 require 包。
  • Mocking,在 mock 包下。
  • 测试组件,在 suite 包下。

assert 包

assert 包提供了一系列很方便的断言方法,简化你的测试代码。如

package yours
import (
  "testing"
  "github.com/stretchr/testify/assert"
)
func TestSomething(t *testing.T) {
  // 断言相等
  assert.Equal(t, 123, 123, "they should be equal")
  // 断言不等
  assert.NotEqual(t, 123, 456, "they should not be equal")
  // 断言为 nil 
  assert.Nil(t, object)
}

assert 包的函数的第一个参数为 testing.T,用于执行 go test 时输出信息。

如果你有很多个断言,可以调用New方法实例化 Assertions 结构体,然后就可以省略testing.T参数了。上面的代码,可以简化成

func TestSomething(t *testing.T) {
  // 实例化 assertion 结构体,下面的断言都不用传入 t 作为第一个参数了。
  assert := assert.New(t)
  // 断言相等
  assert.Equal(123, 123, "they should be equal")
  // 断言不等
  assert.NotEqual(123, 456, "they should not be equal")
  // 断言为 nil 
  assert.Nil(object)
}

assert 失败的话,底层调用 t.Errorf 来输出错误信息。也就是说,断言失败并不会中停止测试。

assert 包的断言函数,返回值是 bool 类型,表示断言的成功或失败。 我们可以根据返回值,进一步做断言。如

// 当 object 不为 nil 的时候,进一步断言 object.Value 的值
if assert.NotNil(t, object) {
  assert.Equal(t, "Something", object.Value)
}

assert 包提供的断言类型非常多,包括对比变量、json、目录、Http 响应等。完整列表见:pkg.go.dev/github.com/…

require 包

require 包提供的函数和 assert 包是一样的,区别是:

  • require 包如果断言失败,底层调用 t.FailNow, 会立刻中断当前的测试,所以也不会有返回值。
  • assert 包如果断言失败,底层调用 t.Errorf,返回 false,不会中断测试。

mock 包

单元测试一般仅限于测试本服务,对于别的服务的调用(比如数据库),我们可以创建 Mock 对象来模拟对其他服务的调用。

和别的语言一样,Mock 对象我们可以通过工具自动生成。mockery(github.com/vektra/mock…) 工具可以根据 golang 的 interface,生成类似下面的 Mock 对象。

package yours
import (
  "testing"
  "github.com/stretchr/testify/mock"
)
// Mock 对象,会依赖 mock.Mock
type MyMockedObject struct{
  mock.Mock
}
// 要 mock 的接口的方法
func (m *MyMockedObject) DoSomething(number int) (bool, error) {
  args := m.Called(number)
  return args.Bool(0), args.Error(1)
}

我们可以调用 Mock 对象的 On 方法,设置对应方法的参数和返回值。如

// 测试
func TestSomething(t *testing.T) {
  // 实例化 Mock 对象
  testObj := new(MyMockedObject)
  // 设置预期,当调用 testObj.DoSomething(123)时,返回 true, nil
  testObj.On("DoSomething", 123).Return(true, nil)
  // 我们要测试的函数
  targetFuncThatDoesSomethingWithObj(testObj)
  // 断言符合预期,即 testObj.DoSomething(123) 会被调用
  testObj.AssertExpectations(t)
}

On方法设置预期(expectations)时,传入的参数可以使用 mock.Anything,表示任何值都行。如

  // 设置预期,当调用 DoSomething 时,返回 ture,nil
  testObj.On("DoSomething", mock.Anything).Return(true, nil)

如果有多个 mock 对象需要 AssertExpectations,如

testObj1.AssertExpectations(t)
testObj2.AssertExpectations(t)
testObj3.AssertExpectations(t)

可以使用 mock.AssertExpectations 优化

mock.AssertExpectations(t, testObj1, testObj2, testObj3)

mock.Mock 还有一些很实用的常用断言,如:

  • AssertCalled 断言被调用
  • AssertNotCalled 断言没被调用
  • AssertExpectations 断言 On 和 Return 设置的参数和返回值的方法,有被调用
  • AssertNumberOfCalls 断言调用次数

完整的列表可以查看: pkg.go.dev/github.com/…

suite 包

如果你有别的面向对象语言的经验,用 suite 包写单元测试可能更符合你的习惯。我们可以自定义一个结构体,它依赖 suite.Suite,它所有的以 Test 开头的函数,都是一个测试。

import (
    "testing"
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/suite"
)
// 依赖 suite.Suite
type ExampleTestSuite struct {
    suite.Suite
    VariableThatShouldStartAtFive int
}
// 每个测试运行前,会执行
func (suite *ExampleTestSuite) SetupTest() {
    suite.VariableThatShouldStartAtFive = 5
}
// 所有以“Test”开头的方法,都是一个测试
func (suite *ExampleTestSuite) TestExample() {
    assert.Equal(suite.T(), 5, suite.VariableThatShouldStartAtFive)
}
// 用于 'go test' 的入口
func TestExampleTestSuite(t *testing.T) {
    suite.Run(t, new(ExampleTestSuite))
}

除了 SetupTest,suite.Suite 还有一些钩子:

TearDownTest 每个测试之后执行

SetupSuite Suite 开始之前执行一次,在所有测试之前执行

TearDownSuite Suite 结束之后执行一次,在所有测试之后执行

更多的介绍可以查看官网:pkg.go.dev/github.com/…

引用

pkg.go.dev/github.com/…

以上就是Go单元测试利器testify使用示例详解的详细内容,更多关于Go 单元测试testify的资料请关注编程网其它相关文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Go单元测试利器testify使用示例详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Go单元测试利器testify使用示例详解

这篇文章主要为大家介绍了Go单元测试利器testify使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2022-12-15

Go 语言进阶单元测试示例详解

这篇文章主要为大家介绍了Go 语言进阶单元测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-28

Go语言工程实践单元测试基准测试示例详解

这篇文章主要为大家介绍了Go语言工程实践单元测试基准测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-05

利用Python中unittest实现简单的单元测试实例详解

前言 单元测试的重要性就不多说了,可恶的是Python中有太多的单元测试框架和工具,什么unittest, testtools, subunit, coverage, testrepository, nose, mox, mock, fix
2022-06-04

深入理解Python单元测试unittest的使用示例

软件测试 大型软件系统的开发是一个很复杂的过程,其中因为人的因素而所产生的错误非常多,因此软件在开发过程必须要有相应的质量保证活动,而软件测试则是保证质量的关键措施。正像软件熵(software entropy)所描述的那样:一个程序从设计
2022-06-04

前端自动化测试Vue中TDD和单元测试示例详解

这篇文章主要为大家介绍了前端自动化测试Vue中TDD和单元测试示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-02-14

go并发利器sync.Once使用示例详解

这篇文章主要为大家介绍了go并发利器sync.Once使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-03-14

ViewModel中StateFlow和SharedFlow单元测试使用详解

这篇文章主要为大家介绍了ViewModel中StateFlow和SharedFlow单元测试使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-17

Java读写锁ReadWriteLock的创建使用及测试分析示例详解

这篇文章主要为大家介绍了Java读写锁ReadWriteLock的创建使用及测试分析示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
2023-01-12

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录