[Go] Pre- and post-calls for Go unit testing--TestMain

For unit testing in the Go language, the standard library testing package is usually used. It starts with Test and the parameter list must be t *testing.T. For stress testing, it is used b *testing.B.

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

In Goland, just click the green button to run it directly. But if we need to call some common code before each unit test runs, that won't work. In this case, certain functions must be explicitly called in the unit test function, which will inevitably lead to the existence of a lot of redundant code.

The Go language testing framework provides an annotation mechanism similar to JUnit 4, that is, pre-call and post-call @Before.@After

In the unit test file, write a function named TestMain , and the name must be this! The parameters are m *testing.M, the code is as follows:

```go package mypackage

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

// Function func setup() for pre-call { fmt.Println("Set pre-call") // Perform your preparation work }

// Test function func TestMain(m *testing.M) { // Set up the pre-call setup()

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

// 执行清理工作
teardown()

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

}

//Cleanup function func teardown() { fmt.Println("Perform cleanup") //Perform your cleanup }

// Specific test func TestSomething(t *testing.T) { // Execute your test logic fmt.Println("Execute test logic") }

```The TestMain functions in each test file are independent of each other and do not interfere with each other. Next, let’s look at a specific example, taking connecting to Redis Server and storing data as an example:

```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)

// When performing an operation, you need to obtain the connection status := client.Ping(ctx) fmt.Println(status.Result()) }

// Test function 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 那样强大,因为没法拿到切入点,进而没法控制调用的细节。

Guess you like

Origin blog.csdn.net/weixin_45254062/article/details/131140805
Go