2016-05-16 79 views
2

假设我有一个简单的应用程序,它从stdin中读取行并简单地将它回显给stdout。例如:如何编写写入标准输入的Go测试?

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 

我明明做一些不正确这里。我应该如何去测试这种类型的代码?

回答

2

这是一个写入标准输入并从标准输出中读取的例子。请注意,它不起作用,因为输出中首先包含“>”。不过,您可以修改它以适应您的需求。

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

我已经从输出中删除了“>”并使用了你的TestInput函数。我得到了一系列的约100个重复的失败,看起来是这样的: === RUN TestInput ---失败:TestInput(5.17s) \t echo_test.go:36:求购:ABC \t \t,得到: --- FAIL:TestInput(5.15s) \t \t \t echo_test.go:36:通缉:ABC \t \t \t \t,GOT:--- FAIL:TestInput(5.13s) \t \t \t \t \t echo_test.go :36:通缉:abc ...等等。 –

+0

当我移除“>”时,它对我很好。你提供了正确的命令来运行? –

+0

我将命令更改为os.Args [0]。 –

3

而不是做在mainstdinstdout的一切,你可以定义一个函数,它接受一个io.Readerio.Writer作为参数和做任何你想要做的事。 main然后可以调用该函数,并且您的测试函数可以直接测试该函数。

+0

是的,我曾考虑过这一点,我期望这是我将不得不做的。我只是想知道是否有办法直接访问main的stdin/stdout。 –