[Go]Go单元测试的前置和后置调用--TestMain

进行 Go 语言的单元测试通常使用标准库 testing 包,以 Test 开头,参数列表必须为 t *testing.T,做压测的话使用的是 b *testing.B

go func TestHello(t *testing.T) { fmt.Println("Hello World") }

在 Goland 中,直接点击绿色按钮直接就可以运行了。但是假如我们需要每次单元测试运行前调用一些公共的代码,那么就不行了,这样就必须在单元测试函数中显式地调用某些函数,这必然会导致大量冗余代码的存在。

Go 语言的测试框架提供了一种类似于 JUnit 4 的 @Before@After 注解的机制,也就是前置调用和后置调用。

在单元测试文件中,编写一个名称为 TestMain 的函数,而且名称必须得是这个!参数为 m *testing.M,代码如下:

```go package mypackage

import ( "fmt" "os" "testing" )

// 前置调用的函数 func setup() { fmt.Println("设置前置调用") // 执行你的准备工作 }

// 测试函数 func TestMain(m *testing.M) { // 设置前置调用 setup()

// 运行测试
code := m.Run()

// 执行清理工作
teardown()

// 退出测试
os.Exit(code)

}

// 清理函数 func teardown() { fmt.Println("执行清理工作") // 执行你的清理工作 }

// 具体测试 func TestSomething(t *testing.T) { // 执行你的测试逻辑 fmt.Println("执行测试逻辑") }

``` 每个测试文件中的 TestMain 函数都是彼此独立的互不干扰。接下来看一个具体的例子,以连接 Redis Server 并存入数据为例:

```go package main

import ( "context" "fmt" "os" "testing" "time"

"github.com/go-redis/redis/v8" )

var client *redis.Client var ctx = context.Background()

// 前置调用的函数 func before() { opt, err := redis.ParseURL("redis://default:[email protected]:6379/0?dial_timeout=1") if err != nil { panic(err) } client = redis.NewClient(opt) fmt.Println(client)

// 执行操作时,需要获取连接 status := client.Ping(ctx) fmt.Println(status.Result()) }

// 测试函数 func TestMain(m *testing.M) { before() code := m.Run() after() os.Exit(code) }

func after() { _ = client.Close() }

func TestSetString(t testing.T) { status := client.Set(ctx, "name", "luobdia", time.Second10) fmt.Println(status.Result()) } ```

go-redis 包的客户端对象被放到了全局的位置,以避免每次单元测试手动创建。这样看起来是不是有面向切面编程的味道了?但是还做不到完全的像 AOP 那样强大,因为没法拿到切入点,进而没法控制调用的细节。

猜你喜欢

转载自blog.csdn.net/weixin_45254062/article/details/131140805
今日推荐