一尘不染

如何编写写入stdin的Go测试?

go

假设我有一个简单的应用程序,可以从stdin读取行并将其回显到stdout。例如:

package main

import (
    "bufio"
    "fmt"
    "io"
    "os"
)

func main() {
    reader := bufio.NewReader(os.Stdin)
    for {
        fmt.Print("> ")
        bytes, _, err := reader.ReadLine()
        if err == io.EOF {
            os.Exit(0)
        }
        fmt.Println(string(bytes))
    }
}

我想编写一个测试案例,该案例写入stdin,然后将输出与输入进行比较。例如:

package main

import (
    "bufio"
    "io"
    "os"
    "os/exec"
    "testing"
)

func TestInput(t *testing.T) {
    subproc := exec.Command(os.Args[0])
    stdin, _ := subproc.StdinPipe()
    stdout, _ := subproc.StdoutPipe()
    defer stdin.Close()

    input := "abc\n"

    subproc.Start()
    io.WriteString(stdin, input)
    reader := bufio.NewReader(stdout)
    bytes, _, _ := reader.ReadLine()
    output := string(bytes)
    if input != output {
        t.Errorf("Wanted: %v, Got: %v", input, output)
    }
    subproc.Wait()
}

跑步go test -v给我以下内容:

=== RUN   TestInput
--- FAIL: TestInput (3.32s)
    echo_test.go:25: Wanted: abc
        , Got: --- FAIL: TestInput (3.32s)
FAIL
exit status 1

我显然在这里做错了什么。我应该如何测试这种类型的代码?


阅读 333

收藏
2020-07-02

共1个答案

一尘不染

这是一个写入stdin并从stdout读取的示例。请注意,它不起作用,因为输出首先包含“>”。不过,您可以对其进行修改以适合您的需求。

func TestInput(t *testing.T) {
    subproc := exec.Command("yourCmd")
    input := "abc\n"
    subproc.Stdin = strings.NewReader(input)
    output, _ := subproc.Output()

    if input != string(output) {
        t.Errorf("Wanted: %v, Got: %v", input, string(output))
    }
    subproc.Wait()
}
2020-07-02