2016-05-16 9 views
2

Angenommen, ich habe eine einfache Anwendung, die Zeilen von stdin liest und sie einfach auf stdout zurückgibt. Zum Beispiel:Wie kann ich einen Go-Test schreiben, der in stdin schreibt?

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

Ich möchte einen Testfall schreiben, die auf stdin schreibt und vergleicht dann den Ausgang mit dem Eingang. Zum Beispiel:

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 Laufen gibt mir folgendes:

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

ich offensichtlich etwas falsch hier tue. Wie sollte ich diese Art von Code testen?

Antwort

2

Hier ist ein Beispiel, das auf stdin schreibt und von stdout liest. Beachten Sie, dass es nicht funktioniert, da die Ausgabe zuerst ">" enthält. Dennoch können Sie es an Ihre Bedürfnisse anpassen.

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

Ich habe das ">" aus meiner Ausgabe entfernt und Ihre TestInput-Funktion verwendet. Ich erhalte eine Reihe von etwa 100 Wiederholungsfehler, die wie folgt aussehen: === RUN TestInput --- FAIL: TestInput (5.17s) \t echo_test.go: 36: Gesucht: abc \t \t, Got: --- FAIL: TestInput (5.15s) \t \t \t echo_test.go: 36: gewünscht: abc \t \t \t \t, Got: --- FAIL: TestInput (5.13s) \t \t \t \t \t echo_test.go : 36: Gesucht: abc ... und so weiter. –

+0

Es funktioniert gut für mich, wenn Sie das ">" entfernen. Haben Sie den richtigen Befehl zum Ausführen angegeben? –

+0

Ich habe den Befehl in os.Args [0] geändert. –

3

Statt alles zu tun, in main mit stdin und stdout, können Sie eine Funktion definieren, die eine io.Reader und eine io.Writer als Parameter nimmt und tut, was Sie es tun wollen. main könnte dann diese Funktion aufrufen und Ihre Testfunktion könnte diese Funktion direkt testen.

+0

Ja, ich habe darüber nachgedacht und ich erwarte, dass dies das ist, was ich tun muss. Ich habe mich nur gefragt, ob es einen Weg gibt, direkt auf main's stdin/stdout zuzugreifen. –

Verwandte Themen