Golang Test
目录
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相关推荐
- 【Golang源码分析】Go Web常用程序包gorilla/mux的使用与源码简析
目录[阅读时间:约10分钟] 一.概述 二.对比: gorilla/mux与net/http DefaultServeMux 三.简单使用 四.源码简析 1.NewRouter函数 2.HandleF ...
- 基于Golang的简单web服务程序开发——CloudGo
基于Golang的简单web服务程序开发--CloudGo[阅读时间:约10分钟] 一.概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 (1)基本要求 (2)扩展要求 三.具体 ...
- CentOS Docker安装配置部署Golang web helloworld
目录[阅读时间:约5分钟] 一.Docker简介 二.Docker的安装与配置[CentOS环境] 三.Docker部署Golang web helloworld 四.Docker与虚拟机的区别 五. ...
- 【ReactiveX】基于Golang pmlpml/RxGo程序包的二次开发
基于Golang pmlpml/RxGo程序包的二次开发[阅读时间:约20分钟] 一.ReactiveX & RxGo介绍 1.ReactiveX 2.RxGo 二.系统环境&项目介绍 ...
- 【golang程序包推荐分享】分享亿点点golang json操作及myJsonMarshal程序包开发的踩坑经历 :)
目录[阅读时间:约5分钟] 一.概述 1.Json的作用 2.Go官方 encoding/json 包 3. golang json的主要操作 二.Json Marshal:将数据编码成json字符串 ...
- 基于Golang的对象序列化的程序包开发——myJsonMarshal
基于Golang的对象序列化的程序包开发--myJsonMarshal[阅读时间:约10分钟] 一.对象序列化概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 三.具体程序设计及 ...
- 【golang程序包推荐分享】go-ini、viper、godoc
[golang程序包推荐&分享]go-ini.viper.godoc 一.go-ini 1.程序包简介 2.下载安装 3.简单使用[截取自官网] 二.viper 1.程序包简介 2.下载安装 ...
- 基于Golang的监听读取配置文件的程序包开发——simpleConfig_v1
基于Golang的监听&读取配置文件的程序包开发--simpleConfig_v1 [阅读时间:约10分钟] 一.配置文件概述 二.系统环境&项目介绍 1.系统环境 2.项目的任务要求 ...
- 基于Golang的CLI 命令行程序开发
基于Golang的CLI 命令行程序开发 [阅读时间:约15分钟] 一. CLI 命令行程序概述 二. 系统环境&项目介绍&开发准备 1.系统环境 2.项目介绍 3.开发准备 三.具体 ...
- centos使用镜像源轻松配置golang+vscode的方法
Title:centos使用镜像源轻松配置golang+vscode的方法 (阅读时间:约5分钟) 零.序言 最近笔者在上一门名为服务计算的课程,在老师的作业博客中提到,安装golang+vscode ...
最新文章
- 人脸识别技术在法国:质疑声中的先行者
- Fedora 18下 升级内核后VirtualBox不能正常使用的问题
- python sort函数返回值_lambda函数与箭头函数在集合内置函数应用中的对照学习
- 预处理指令的开始和结束
- 区分错误类型_数仓|几种SQL隐藏的错误,你遇到过吗?
- 人脸方向学习(十五):Face Detection-RetinaFace解读
- Drupal是基于PHP语言编写的用于开发网站的开发型CMF
- 详解Android常用抓包工具的使用方法、技巧-学习笔记20220416
- 实用:旋转矩阵与方向余弦矩阵(DCM)
- < 数据结构 > 树与二叉树
- GPIO output level 和 GPIO Pull-up/Pull-down的区别
- C. Good Subarrays
- Windows10设置暗色主题
- c#webservice接口調用_Windows 桌面应用开发之 C# 调用 WebService 接口
- 电容笔和Apple pencil区别有什么?双十一值得入手的电容笔推荐
- Github上的开源工具帮助你实现“十一”回家的愿望
- python 内置函数 reversed()
- vue组件间通信六种方式
- cn2an:中文数字转阿拉伯数字
- 【互联网寒冬】经历裁员,拿20W被迫去大厂
热门文章
- 远程办公招聘平台汇总 | 三线程序员的福音
- 中国电信计算机技术类笔试题,2019内蒙古中国电信考试试题——专业知识(一)...
- A. Rook, Bishop and King
- 搜索相关度算法 TF-IDF与BM25
- 怎么把计算机上的资源进行共享,如何实现两台电脑资源共享
- 动态规划-01背包问题
- 抖音里最火爆的App之一の拍照扫描文字识别
- c语言斐波那契数列前20项和,,c语言利用数组求斐波那契数列的前20项
- 计算机在测控技术与仪器中的应用,测控技术与仪器在实践中的应用分析
- 同源基因鉴定 | OrthoFinder 2.0 + MAFFT + IQtree