如何在不等待测试的情况下在goroutine中测试结果

har*_*fan 11 testing go goroutine

我在golang做ut的时候,有时候需要在goroutine里面测试一下结果,我是用time.Sleep来测试的,不知道有没有更好的测试方式。

假设我有一个这样的示例代码

func Hello() {
    go func() {
        // do something and store the result for example in db
    }()
    // do something
}
Run Code Online (Sandbox Code Playgroud)

然后当我测试 func 时,我想在 goroutine 中测试这两个结果,我这样做:

 func TestHello(t *testing.T) {
        Hello()
        time.Sleep(time.Second) // sleep for a while so that goroutine can finish
        // test the result of goroutine
 }
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来测试这个?

基本上,在真正的逻辑中,我不在乎 goroutine 中的结果,我不需要等待它完成。但在测试中,我想在完成后检查。

Fli*_*mzy 7

“我如何测试 X?”的大多数问题 往往归结为X太大。

对于您的情况,最简单的解决方案是不在测试中使用 goroutine。单独测试每个功能。将您的代码更改为:

func Hello() {
    go updateDatabase()
    doSomething()
}

func updateDatabase() {
    // do something and store the result for example in db
}

func doSomething() {
    // do something
}
Run Code Online (Sandbox Code Playgroud)

updateDatabase然后为和编写单独的测试doSomething

  • 有时,您需要测试带有 func 的 goroutine 是否实际上已使用预期的参数集进行了调用。那么这样的情况应该如何测试呢? (10认同)

fai*_*din 5

如果你真的想检查 goroutine 的结果,你应该使用这样的通道:

package main

import (
    "fmt"
)

func main() {
    // in test
    c := Hello()
    if <-c != "done" {
        fmt.Println("assert error")
    }

    // not want to check result
    Hello()
}

func Hello() <-chan string {
    c := make(chan string)
    go func() {
        fmt.Println("do something")
        c <- "done"
    }()
    return c
}
Run Code Online (Sandbox Code Playgroud)

https://play.golang.org/p/zUpNXg61Wn