Golang测试带通道的例行程序

时间:2018-10-02 10:49:12

标签: go goroutine

我具有以下功能,该功能在执行时将点打印到终端 某些过程中,代码按预期工作,但现在我要对其进行测试。 我该怎么做

func printdot(finish <-chan struct{}) {
    t := time.NewTicker(time.Second)
    defer t.Stop()
    for {
        select {
        case <-t.C:
            fmt.Print(".")
        case <-finish:
            return
        }
    }
}

这是测试

func Test_printdot(t *testing.T) {

    finish := make(chan struct{})
    start := time.Now()
    go printdot(finish)
    time.Sleep(1 * time.Second)

    sec := time.Since(start).Seconds()
    switch int(sec) {
    case 0:
        // Output:
    case 1:
        // Output: .
    case 2:
        // Output: ..
    case 3:
        // Output: ...
    default:
        t.Error(“Too much time…”)
    }

     close(finish)
}

现在,即使Im正在使用完成代码,该测试仍在继续运行,没有任何想法如何改进它?

1 个答案:

答案 0 :(得分:1)

关闭通道不会发送数据,因此代码永远不会到达goroutine中的return。与范围运算符一起使用的技巧。你可以做这样的事情

package main

import (
    "fmt"
    "time"
    "sync"
)

func printdot(finish <-chan struct{}, wg sync.WaitGroup) {
    t := time.NewTicker(time.Second)
    defer t.Stop()
    defer wg.Done()
    for {
        select {
        case <-t.C:
            fmt.Print(".")
        case <-finish:
            return
        }
    }
}

请注意,我在goroutine结束时为“等待”添加了sync.WaitGroup

package main


import (
        "fmt"
        "time"
        "sync"
        "testing"

    )

func Test_printdot(t *testing.T) {
    var wg sync.WaitGroup
    wg.Add(1)
    finish := make(chan struct{})
    start := time.Now()
    go printdot(finish, wg)
    time.Sleep(3 * time.Second)

    sec := time.Since(start).Seconds()
    switch int(sec) {
    case 0:
        // Output:
    case 1:
        // Output: .
    case 2:
        // Output: ..
    case 3:
        // Output: ...
    default:
        t.Error("Too much time…")
    }

    finish <- struct{}{}
    wg.Wait()
}