目录

1. GoConvey

Installation

Example

2. Mock DB

Install

Example

3. Generating code

Example

4. GoMock

Installation

Example


In this page, i integrate GoConvey, sqlmock, go generate and GoMock to test golang code.

1. GoConvey

GoConvey is a yummy Go testing tool for gophers. Works with go test.

Features:

  • Directly integrates with go test

  • Fully-automatic web UI (works with native Go tests, too)

  • Huge suite of regression tests

  • Shows test coverage (Go 1.2+)

  • Readable, colorized console output (understandable by any manager, IT or not)

  • Test code generator

  • Desktop notifications (optional)

  • Immediately open problem lines in Sublime Text (some assembly required)

Installation

$ go get github.com/smartystreets/goconvey

Example

// UnmarshalToMap unmarshal xml into map in util.go
func UnmarshalToMap(b []byte) map[string]interface{} {decoder := xml.NewDecoder(bytes.NewBuffer(b))s := NewStack()for {t, err := decoder.Token()if err != nil {if err == io.EOF {break}}
​switch ele := t.(type) {case xml.StartElement:s.Push(ele)case xml.CharData:s.Push(string(xml.CharData(ele)))case xml.EndElement:entry := make(map[string]interface{})var val interface{}for {p := s.Pop()
​// push key [start] val into stackif start, ok := p.(xml.StartElement); ok {node := make(map[string]interface{})node[start.Name.Local] = vals.Push(node)break}
​switch p.(type) {case map[string]interface{}:// handle pushed mapnode := p.(map[string]interface{})for k, v := range node {entry[k] = v}if val == nil {val = entry}default:// handle xml char dataval = p}}}
​}
​return s.Pop().(map[string]interface{})
}
// in util_test.go
func TestUnmarshalToMap(t *testing.T) {convey.Convey("Failed unmarshal xml to map", t, func() {b := []byte(`<?xml version="1.0"?><xml><appid><![CDATA[wxxxx]]></appid><case><cash_fee><![CDATA[1]]></cash_fee></case><mch_id><![CDATA[xxx]]></mch_id><nonce_str><![CDATA[KptCSXZh1qBjK8wb]]></nonce_str><out_refund_no_0><![CDATA[1519535580802]]></out_refund_no_0><out_trade_no><![CDATA[1515845954891]]></out_trade_no><refund><refund_account_0><![CDATA[REFUND_SOURCE_UNSETTLED_FUNDS]]></refund_account_0><refund_channel_0><![CDATA[ORIGINAL]]></refund_channel_0><refund_count>1</refund_count><refund_fee>1</refund_fee><other_refund><refund_fee_0>1</refund_fee_0><refund_id_0><![CDATA[50000405502018022503594217469]]></refund_id_0><refund_recv_accout_0><![CDATA[支付用户的零钱]]></refund_recv_accout_0><refund_status_0><![CDATA[SUCCESS]]></refund_status_0></other_refund><refund_success_time_0><![CDATA[2018-02-25 13:13:03]]></refund_success_time_0></refund><result_code><![CDATA[SUCCESS]]></result_code><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg><sign><![CDATA[E8A30F02296C6169860A92C2D52AD5A8]]></sign><total_fee><![CDATA[1]]></total_fee><transaction_id><![CDATA[4200000100201801133414066940]]></transaction_id></xml>`)m := UnmarshalToMap(b)
​convey.So(m["xml"].(map[string]interface{})["appid"], assertions.ShouldEqual, "wxxxx")convey.So((m["xml"].(map[string]interface{})["case"].(map[string]interface{}))["cash_fee"], assertions.ShouldEqual, "1")convey.So(((m["xml"].(map[string]interface{})["refund"].(map[string]interface{}))["other_refund"].(map[string]interface{}))["refund_fee_0"], assertions.ShouldEqual, "1")})
}

2. Mock DB

sqlmock is a mock library implementing sql/driver. Which has one and only purpose - to simulate any sql driver behavior in tests, without needing a real database connection.

  • supports concurrency and multiple connections.

  • supports go1.8 Context related feature mocking and Named sql parameters.

  • does not require any modifications to your source code.

  • the driver allows to mock any sql driver method behavior.

  • has strict by default expectation order matching.

  • has no third party dependencies.

Install

go get github.com/DATA-DOG/go-sqlmock

Example

func mockGormDB() (*gorm.DB, sqlmock.Sqlmock, error) {db, mock, err := sqlmock.New()if err != nil {return nil, nil, err}// GORMgormDB, err := gorm.Open("mysql", db) // Can be any connection stringif err != nil {return nil, nil, err}
​gormDB.LogMode(true)
​return gormDB, mock, nil
}
​
func TestMySQLChannelRepository_Get(t *testing.T) {Convey("Test ChannelRepository Get is failed!", t, func() {db, mock, err := mockGormDB()So(err, ShouldBeNil)defer db.Close()
​now := time.Now()rows := sqlmock.NewRows([]string{"id", "chl_type", "chl_name", "chl_label", "chl_desc", "chl_logo", "state", "created_at", "created_by", "updated_at", "updated_by"}).AddRow(1, "wx_app", "微信App支付", "微信App支付", "微信 App 支付", "wx_app.png", 1, &now, "admin", &now, "admin")mock.ExpectQuery(regexp.QuoteMeta("SELECT * FROM `op_channel` WHERE (`op_channel`.`id` = 1)")).WillReturnRows(rows)
​chlRepo := MySQLChannelRepository{GormRepository: gd.GormRepository{DB: db},}
​var chl *model.OpChannelchl, err = chlRepo.Get(1)So(err, ShouldBeNil)So(chl.Id, ShouldEqual, 1)})
}

3. Generating code

go generateis a command to generating code buildin golang release 1.4 and later.

Example

Add comments go:generate mockgen -destination mock_repo/mock_chl_repo.go github.com/cy18cn/octopus/mch/repository ChannelRepository for interface.

//go:generate mockgen -destination mock_repo/mock_chl_repo.go github.com/cy18cn/octopus/mch/repository ChannelRepository
type ChannelRepository interface {Get(id uint64) (*model.OpChannel, error)ListAll() ([]*model.OpChannel, error)
}

Run command go generate to generate GoMock struct implement ChannelRepository in file mock_repo/mock_chl_repo.go.

// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/cy18cn/octopus/mch/repository (interfaces: ChannelRepository)
​
// Package mock_repository is a generated GoMock package.
package mock_repository
​
import (model "github.com/cy18cn/octopus/mch/model"gomock "github.com/golang/mock/gomock"reflect "reflect"
)
​
// MockChannelRepository is a mock of ChannelRepository interface
type MockChannelRepository struct {ctrl     *gomock.Controllerrecorder *MockChannelRepositoryMockRecorder
}
​
// MockChannelRepositoryMockRecorder is the mock recorder for MockChannelRepository
type MockChannelRepositoryMockRecorder struct {mock *MockChannelRepository
}
​
// NewMockChannelRepository creates a new mock instance
func NewMockChannelRepository(ctrl *gomock.Controller) *MockChannelRepository {mock := &MockChannelRepository{ctrl: ctrl}mock.recorder = &MockChannelRepositoryMockRecorder{mock}return mock
}
​
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockChannelRepository) EXPECT() *MockChannelRepositoryMockRecorder {return m.recorder
}
​
// Get mocks base method
func (m *MockChannelRepository) Get(arg0 uint64) (*model.OpChannel, error) {m.ctrl.T.Helper()ret := m.ctrl.Call(m, "Get", arg0)ret0, _ := ret[0].(*model.OpChannel)ret1, _ := ret[1].(error)return ret0, ret1
}
​
// Get indicates an expected call of Get
func (mr *MockChannelRepositoryMockRecorder) Get(arg0 interface{}) *gomock.Call {mr.mock.ctrl.T.Helper()return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockChannelRepository)(nil).Get), arg0)
}
​
// ListAll mocks base method
func (m *MockChannelRepository) ListAll() ([]*model.OpChannel, error) {m.ctrl.T.Helper()ret := m.ctrl.Call(m, "ListAll")ret0, _ := ret[0].([]*model.OpChannel)ret1, _ := ret[1].(error)return ret0, ret1
}
​
// ListAll indicates an expected call of ListAll
func (mr *MockChannelRepositoryMockRecorder) ListAll() *gomock.Call {mr.mock.ctrl.T.Helper()return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListAll", reflect.TypeOf((*MockChannelRepository)(nil).ListAll))
}

4. GoMock

GoMock is a mocking framework for the Go programming language. It integrates well with Go's built-in testing package, but can be used in other contexts too.

Installation

go get github.com/golang/mock/mockgen

Example

var (chls = []*model.OpChannel{{Id:       1,ChlType:  "wx_app",ChlName:  "微信App支付",ChlLabel: "微信App支付",ChlDesc:  "微信 App 支付",ChlLogo:  "wx_app.png",State:    1,},{Id:       2,ChlType:  "wx_jsapi",ChlName:  "微信jsapi支付",ChlLabel: "微信jsapi支付",ChlDesc:  "微信 jsapi 支付",ChlLogo:  "wx_jsapi.png",State:    1,},{Id:       3,ChlType:  "wx_mini",ChlName:  "微信mini支付",ChlLabel: "微信mini支付",ChlDesc:  "微信 mini 支付",ChlLogo:  "wx_mini.png",State:    1,},}
​pChls = []*model.OpPayChannel{{Id:        1,AppId:     "134567",ChlId:     1,PayConfig: "",State:     1,},{Id:        2,AppId:     "134567",ChlId:     2,PayConfig: "",State:     1,},}
​app = &model.OpMchApp{Id:      1,MchId:   "123456",MchName: "测试",AppName: "测试",Appid:   "134567",MchKey:  "15234212d4sa4df523s4af",State:   1,}
)
​
func TestPayChlService_pChannelList(t *testing.T) {Convey("", t, func() {ctrl := gomock.NewController(t)chlRepo := mock_repository.NewMockChannelRepository(ctrl)payChlRepo := mock_repository.NewMockPayChlRepository(ctrl)mchAppRepo := mock_repository.NewMockMchAppRepository(ctrl)
​chlRepo.EXPECT().ListAll().Return(chls, nil)payChlRepo.EXPECT().FindByAppId("134567").Return(pChls, nil)
​pService := &PayChlService{channelRepo: chlRepo,payChlRepo:  payChlRepo,mchAppRepo:  mchAppRepo,}
​resp, err := pService.pChannelList("134567")So(err, ShouldBeNil)So(len(resp), ShouldEqual, 3)So(resp[2].State, ShouldEqual, 0)})
}

Golang Test相关推荐

  1. 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析

    目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...

  2. 基于Golang的简单web服务程序开发——CloudGo

    基于Golang的简单web服务程序开发--CloudGo[阅读时间:约10分钟] 一.概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 (1)基本要求 (2)扩展要求 三.具体 ...

  3. CentOS Docker安装配置部署Golang web helloworld

    目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker部署Golang web helloworld 四.Docker与虚拟机的区别 五. ...

  4. 【ReactiveX】基于Golang pmlpml/RxGo程序包的二次开发

    基于Golang pmlpml/RxGo程序包的二次开发[阅读时间:约20分钟] 一.ReactiveX & RxGo介绍 1.ReactiveX 2.RxGo 二.系统环境&项目介绍 ...

  5. 【golang程序包推荐分享】分享亿点点golang json操作及myJsonMarshal程序包开发的踩坑经历 :)

    目录[阅读时间:约5分钟] 一.概述 1.Json的作用 2.Go官方 encoding/json 包 3. golang json的主要操作 二.Json Marshal:将数据编码成json字符串 ...

  6. 基于Golang的对象序列化的程序包开发——myJsonMarshal

    基于Golang的对象序列化的程序包开发--myJsonMarshal[阅读时间:约10分钟] 一.对象序列化概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 三.具体程序设计及 ...

  7. 【golang程序包推荐分享】go-ini、viper、godoc

    [golang程序包推荐&分享]go-ini.viper.godoc 一.go-ini 1.程序包简介 2.下载安装 3.简单使用[截取自官网] 二.viper 1.程序包简介 2.下载安装 ...

  8. 基于Golang的监听读取配置文件的程序包开发——simpleConfig_v1

    基于Golang的监听&读取配置文件的程序包开发--simpleConfig_v1 [阅读时间:约10分钟] 一.配置文件概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 ...

  9. 基于Golang的CLI 命令行程序开发

    基于Golang的CLI 命令行程序开发 [阅读时间:约15分钟] 一. CLI 命令行程序概述 二. 系统环境&项目介绍&开发准备 1.系统环境 2.项目介绍 3.开发准备 三.具体 ...

  10. centos使用镜像源轻松配置golang+vscode的方法

    Title:centos使用镜像源轻松配置golang+vscode的方法 (阅读时间:约5分钟) 零.序言 最近笔者在上一门名为服务计算的课程,在老师的作业博客中提到,安装golang+vscode ...

最新文章

  1. 人脸识别技术在法国:质疑声中的先行者
  2. Fedora 18下 升级内核后VirtualBox不能正常使用的问题
  3. python sort函数返回值_lambda函数与箭头函数在集合内置函数应用中的对照学习
  4. 预处理指令的开始和结束
  5. 区分错误类型_数仓|几种SQL隐藏的错误,你遇到过吗?
  6. 人脸方向学习(十五):Face Detection-RetinaFace解读
  7. Drupal是基于PHP语言编写的用于开发网站的开发型CMF
  8. 详解Android常用抓包工具的使用方法、技巧-学习笔记20220416
  9. 实用:旋转矩阵与方向余弦矩阵(DCM)
  10. < 数据结构 > 树与二叉树
  11. GPIO output level 和 GPIO Pull-up/Pull-down的区别
  12. C. Good Subarrays
  13. Windows10设置暗色主题
  14. c#webservice接口調用_Windows 桌面应用开发之 C# 调用 WebService 接口
  15. 电容笔和Apple pencil区别有什么?双十一值得入手的电容笔推荐
  16. Github上的开源工具帮助你实现“十一”回家的愿望
  17. python 内置函数 reversed()
  18. vue组件间通信六种方式
  19. cn2an:中文数字转阿拉伯数字
  20. 【互联网寒冬】经历裁员,拿20W被迫去大厂

热门文章

  1. 远程办公招聘平台汇总 | 三线程序员的福音
  2. 中国电信计算机技术类笔试题,2019内蒙古中国电信考试试题——专业知识(一)...
  3. A. Rook, Bishop and King
  4. 搜索相关度算法 TF-IDF与BM25
  5. 怎么把计算机上的资源进行共享,如何实现两台电脑资源共享
  6. 动态规划-01背包问题
  7. 抖音里最火爆的App之一の拍照扫描文字识别
  8. c语言斐波那契数列前20项和,,c语言利用数组求斐波那契数列的前20项
  9. 计算机在测控技术与仪器中的应用,测控技术与仪器在实践中的应用分析
  10. 同源基因鉴定 | OrthoFinder 2.0 + MAFFT + IQtree