【问题标题】:Test exec that requires interactive input in Golang在 Golang 中需要交互式输入的测试 exec
【发布时间】:2019-02-01 21:21:24
【问题描述】:

我正在尝试在 Go 代码中使用 fzf。我参考了作者给出的here的例子。当我尝试为该函数编写测试时,它被卡住了,因为fzf 需要交互式输入。

代码:

func withFilter(command string, input func(in io.WriteCloser)) []string {
    shell := os.Getenv("SHELL")
    if len(shell) == 0 {
        shell = "sh"
    }
    cmd := exec.Command(shell, "-c", command)
    cmd.Stderr = os.Stderr
    in, _ := cmd.StdinPipe()
    go func() {
        input(in)
        in.Close()
    }()
    result, _ := cmd.Output()
    return strings.Split(string(result), "\n")
}

func filter() []string {
    filtered := withFilter("fzf -m", func(in io.WriteCloser) {
        for i := 0; i < 10; i++ {
            fmt.Fprintln(in, i)
            time.Sleep(5 * time.Millisecond)
        }
    })

    return filtered
}

测试:

func TestFilter(t *testing.T) {
    assert.Equal(t, []string{"1", "2", "3"}, filter())
}

我尝试调试并注意到它卡在cmd.Output()。通过深入挖掘,该命令似乎无限期地等待输入,但是我不确定如何以编程方式提供它。我尝试将\n 写入os.Stdin,但没有成功。

任何人的指点或解释将不胜感激。谢谢。

【问题讨论】:

    标签: shell go exec fzf


    【解决方案1】:

    go 的美妙之处:它的io.Reader/io.Writer 接口。

    您必须提供您的withFilter(以及扩展名filter)方法的读取位置。因此,必须提供in

    // example
    
    func readFrom(reader io.Reader) {
        r := bufio.NewScanner(reader)
    
        for r.Scan() {
            fmt.Println("got", r.Text())
        }
    
        fmt.Println("Done.")
    }
    
    func main() {
        const input = "Now is the winter of our discontent,\nMade glorious summer by this sun of York.\n"
    
        readFrom(strings.NewReader(input))
    
        // okay, with stdin
        readFrom(os.Stdin)
    
    }
    

    如您所见,第一个readFrom 是完全可测试的,您只需将input 变量更改为您想要测试的任何值。第二个readFrom 只会在stdin 关闭时返回。

    解决方案是写信给os.Stdin。将os.Stdin 视为您的操作系统中的一个实现细节,而不是您必须在测试中包含的内容。

    https://play.golang.org/p/D2wzHYrV2TM (os.Stdin 在操场上关闭)

    【讨论】:

    • 我不知道如何将in 提供给filter/withFilter 函数
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-01
    相关资源
    最近更新 更多