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

Say that I have a simple application that reads lines from stdin and simply echoes it back to stdout. For example:

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))
    }
}

I would like to write a test case that writes to stdin and then compares the output to the input. For example:

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
"

    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()
}

Running go test -v gives me the following:

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

I'm obviously doing something incorrect here. How should I go about testing this type of code?

Here is an example that writes to stdin and reads from stdout. Note that it does not work because the output contains "> " at first. Still, you can modify it to suit your needs.

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

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

Instead of doing everything in main with stdin and stdout, you can define a function that takes an io.Reader and an io.Writer as parameters and does whatever you want it to do. main could then call that function and your test function could test that function directly.