golang基础-单元测试与mock

mob604756e80bb7 · · 463 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

golang 单元测试

单元测试介绍

为了保证代码的质量,很多公司都会要求写单元测试。这里介绍两个指标,

  1. 函数覆盖率:函数调用个数/函数个数,通常要求100%
  2. 行覆盖率:走到的行的个数/总函数,通常要求>60%

通过单元测试,我们可以针对不同场景进行测试,是研发自己对质量的把控。 笔者目前所在的公司对单元测试要求很高,并且有替代测试的趋势。

go test

  • go的test一般以xxx_test.go为文件名,xxx并没有特别要求是要实测的文件名
  • TestMain作为初始化test
  • Testxxx(t* testing.T)
  • go test 即可运行单元测试
  • go test --v --test.run funcName 可以指定单测某个方法

创建一个client包进行示例,包结构如下

. ├── client.go ├── client_test.go 复制代码
func TestUser(t *testing.T) {     var u = &User{Age: 15, Name: "alice"}     if u.Age != 15 {         t.Error("age err")     }        if u.Name != "bob" {         t.Error("name err")     }    } 复制代码

由于Name不符合预期,则会有如下提示

--- FAIL: TestUser (0.00s)     client_test.go:28: name err FAIL exit status 1 FAIL test/mocktest 0.005s 复制代码

go convey

goconvey可以很好的支持setup和teardown,goconvey可以在运行单个测试用例前都进行一次状态初始化和销毁。goconvey还有很多已经定义好了的能够直接使用的assert函数,并且可以自定义assert函数。 常用的assert如下:

var (     ShouldEqual          = assertions.ShouldEqual     ShouldNotEqual       = assertions.ShouldNotEqual     ShouldBeGreaterThan          = assertions.ShouldBeGreaterThan     ShouldBeGreaterThanOrEqualTo = assertions.ShouldBeGreaterThanOrEqualTo     ShouldBeLessThan             = assertions.ShouldBeLessThan     ShouldBeLessThanOrEqualTo    = assertions.ShouldBeLessThanOrEqualTo     ShouldBeBetween              = assertions.ShouldBeBetween     ShouldNotBeBetween           = assertions.ShouldNotBeBetween     ShouldBeBetweenOrEqual       = assertions.ShouldBeBetweenOrEqual     ShouldNotBeBetweenOrEqual    = assertions.ShouldNotBeBetweenOrEqual     ShouldContainSubstring    = assertions.ShouldContainSubstring     ShouldNotContainSubstring = assertions.ShouldNotContainSubstring     ShouldPanic        = assertions.ShouldPanic     ShouldBeError      = assertions.ShouldBeError ) 复制代码

使用举例:

func TestUser(t *testing.T) {     convey.Convey("TestUser", t, func() {         var u = &User{Age: 15, Name: "alice"}         convey.So(u.Age, convey.ShouldEqual, 15)          convey.So(u.Name, convey.ShouldEqual, "bob")     })   } 复制代码

由于Name不符合预期,会出现如下提示

  Line 30:   Expected: 'bob'   Actual:   'alice'   (Should be equal) 复制代码

mock

什么是mock

单元测试的时候,如果流程中有第三方依赖怎么办?比如当贷款支付的时候,需要用户的额度,而额度信息存在于另一个微服务,需要rpc拉取。为了解决这种场景,我们可以使用mock这种方式。简单来说,mock就是能指定依赖接口的输入 输出,可以理解为提前插入的固定数据,如此,流程就能正常跑起来。

使用mockery进行mock

限制:

  • 只能针对接口进行mock

使用流程

  • 安装mockery:go get github.com/vektra/mockery/.../
  • mockery -name=接口名,生成mocks目录。

rpc接口定义,接口实现

client.go:

 package rpc  //go:generate mockery -name=Client type Client interface {     Get(key string) (data interface{}, err error) } type ClientImpl struct {     Ct Client } func (p *ClientImpl) Get(key string) (data interface{}, err error) {     if mockCondition  {         return p.Ct.Get(key)     }     // real logic } 复制代码

client_test.go

package rpc  import (     "fmt"     "test/mocktest/mocks"     "testing" ) type User struct {     Age  int      Name string } func TestMock(t *testing.T) {     convey.Convey("TestMock", t, func() {         mc := &mocks.Client{}         var u = &User{Age: 15, Name: "alice"}         mc.On("Get", "alice").Return(u, nil)         ci.Ct = mc         data, err := ci.Get("alice")         convey.So(data.Age, convey.ShouldEqual, 15)     }



有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:mob604756e80bb7

查看原文:golang基础-单元测试与mock

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

463 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传