2016-05-16 110 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。 –