【问题标题】:how to test the result in goroutine without wait in test如何在 goroutine 中测试结果而不在测试中等待
【发布时间】:2018-02-20 08:53:52
【问题描述】:

我在使用golang的时候,有时候需要在goroutine中测试一下结果,我是用time.Sleep来测试的,不知道有没有更好的测试方法。

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

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

然后当我测试 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
 }

有没有更好的测试方法?

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

【问题讨论】:

  • 我听说过使用上下文,但找不到与我的用例类似的确切示例
  • 我不太明白您要做什么。为什么要在 goroutine 中设置 b?如果您不想使用睡眠,请使用等待组。 stackoverflow.com/questions/19208725/…
  • 对不起,我觉得我的例子很混乱,我改变了我的例子

标签: testing go goroutine


【解决方案1】:

如果你真的想检查一个 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
}

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

【讨论】:

    【解决方案2】:

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

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

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

    然后为updateDatabasedoSomething 编写单独的测试。

    【讨论】:

    • 有时您需要测试带有 func 的 goroutine 是否已使用预期的一组参数实际调用。那么这种情况应该如何检验呢?
    • @OlehHolovko:与检查 goroutine 中的任何 func 是否被正确调用的方法几乎相同。可能有一些依赖注入。类似的问题在这里被问过很多次。我建议进行搜索,如果找不到答案,可能需要单独提出一个问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 2019-11-13
    • 2020-06-22
    • 2016-03-20
    • 1970-01-01
    • 2017-09-14
    相关资源
    最近更新 更多