

6.3 利用Go语言接口进行Mock单元测试
source link: https://sunqi.site/posts/old-sun-learning-go-notes-6-3/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

6.3 利用Go语言接口进行Mock单元测试
单元测试重点是对代码逻辑进行测试,也就是证明:为什么你的代码是正确的。Mock测试是单元测试中常用的一种手段,特别是对于代码运行时对环境有严重依赖的,可以在不具备相应环境的情况下运行。例如:数据库、中间件、或者第三方接口等情况。
利用接口可以很容易的构造Mock环境,方便对代码进行单元测试。
在这个实现中,我们定义了一个Obj的结构体,并且定义了getData方法。这里我们假定getData是从第三方服务中获取数据并进行处理。另外我们有一个showTotal的函数用于调用结构体的方法,并且显示出来,相当于后续的程序处理。
如果我们对showTotal进行单元测试的时候,我们会发现需要构建getData的依赖环境才能进行单元测试,所以此时我们可以使用interface构建一个MockObj来伪造getData返回数据,进行不同的场景测试。
package original
import "fmt"
type Obj struct {
name string
}
// This is a real function to connect third party service, like database
func (o Obj) getData() int {
fmt.Printf("This is [%s] environment\n", o.name)
// if we fetch data here
data := map[string]int{
"total": 10,
}
return data["total"]
}
func showTotal(o Obj) int {
total := o.getData()
fmt.Printf("Total count: %v\n", total)
}
func main() {
o := Obj{"Production"}
showTotal(o)
}
首先我们先定义一个接口,定义接口的目的是能让我们的Mock结构体生效
type objInterface interface {
getData() int
}
我们对showTotal的函数入参进行调整,原有入参只接收了Obj这个结构体,我们改成接收接口参数。
func showTotal(o objInterface) int {
total := o.getData()
fmt.Printf("Total count: %v\n", total)
return total
}
Mock结构体
我们新建一个main_test.go的单元测试文件,我们新增一个Mock结构体及Mock的getData方法。
type MockObj struct {}
func (o MockObj) getData() int {
fmt.Printf("This is a mock function using interface\n")
return 100
}
Mock测试
我们新增一个测试用例,如果showTotal能够返回100,则测试成功,否则抛出异常。在测试用例中,我们将定义好的MockObj传给了showTotal,此时showTotal调用了我们定义的Mock方法,所以返回100,单元测试构建成功。
func TestShowTotal(t *testing.T) {
mo := MockObj{}
total := showTotal(mo)
if total != 100 {
t.Log("Mock show total failed!")
t.Fail()
}
}
package main
import "fmt"
type objInterface interface {
getData() int
}
type Obj struct {
name string
}
// This is a real function to connect third party service, like database
func (o Obj) getData() int {
fmt.Printf("This is [%s] environment\n", o.name)
// if we fetch data here
data := map[string]int{
"total": 10,
}
return data["total"]
}
func showTotal(o objInterface) int {
total := o.getData()
fmt.Printf("Total count: %v\n", total)
return total
}
func main() {
o := Obj{"Production"}
showTotal(o)
}
package main
import (
"fmt"
"testing"
)
type MockObj struct {}
func (o MockObj) getData() int {
fmt.Printf("This is a mock function using interface\n")
return 100
}
func TestShowTotal(t *testing.T) {
mo := MockObj{}
total := showTotal(mo)
if total != 100 {
t.Log("Mock show total failed!")
t.Fail()
}
}
运行及结果
运行go test之前,记得要设定环境变量
export GO111MODULE=off
go test
返回如下,我们很清楚的看到了测试中调用了我们的Mock方法
This is a mock function using interface
Total count: 100
PASS
ok _/root/workspace/go/test_interface_unittest 0.003s
Recommend
-
68
-
23
-
36
简介 日常开发中, 测试是不能缺少的. Go 标准库中有一个叫做 testing 的测试框架, 可以用于单元测试和性能测试. 它是和命令 go test 集成使用的. 测试文件是...
-
6
「测试」 - 接口测试 & mock工具Moco 当需要调用第三方HTTP接口时,别人的接口还没完成,可先根据接口定义文档,返回适当的数据,以便开发。在...
-
22
使用Jest进行前端单元测试2021-03-304 分钟对于逻辑复杂、迭代频繁的前端项目,进行单元测试很有必要。 这样可以节省大量E2E测试的时间,保证代码的可靠性,量化评估研发团队、测试团队的产出。 常见的前端单元测试框架,有Mocha、Jasmi...
-
8
这是Go语言单元测试从零到溜系列教程的第3篇,介绍了如何在单元测试中使用gomock和gostub工具mock接口和打桩。 在上一篇《Go单测从零到溜系列2—数据库测试》中,我们介绍了如何...
-
5
编写接口请求库单元测试与 E2E 测试的思考最近在写适配 Mx Space Server 的 JS SDK。因为想写一个正式一点的库,以后真正能派的上用场的,所以写的时候尽量严谨一点。所以单测和 E2E 也是非常重要。先说说我这个接...
-
5
为什么使用Mock进行单元测试?从功能开发完成的定义来看,至少包括:代码本身、文档及单元测试。而往往在实际开发中,由于需求的不停的变化,导致文档及单元测试是开发过程中直接被忽略的内容。反观优秀的开源项目,在全球...
-
6
python3的单元测试模块mock与性能测试模块cProfile首页 - Python/2019-06-14
-
12
Golang高效编写单元测试的技巧之Mock codingcn · 大约12小时之前 · 187...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK