2013-07-03 4 views
6

fmt.Scan/Scanf/Scanlnのユーザー入力に対するテスト方法を教えてください。Goでのユーザー入力に対するテストの書き方

たとえば、関数入力がSTDINの "4 5 \ n"と "1 2 3 4 \ n"を受け入れ、n == 5とarray == [1、2、3、 4]。

package main 

import (
    "fmt" 
) 

// input gets an array from the user. 
func input() (m int, array []int) { 
    fmt.Print("Enter the size of the array, n, and the difference, m: ") 
    var n int 
    _, err := fmt.Scanf("%d %d", &n, &m) 
    if err != nil { 
     panic(err) 
    } 

    fmt.Print("Enter the array as a space seperated string: ") 
    array = make([]int, n) 
    for i := 0; i < n; i++ { 
     _, _ = fmt.Scan(&array[i]) 
    } 

    return m, array 
} 

func main() { 
    m, array := input() 
    fmt.Println(m, array) 
} 

答えて

10

原則を説明するための非常に原案があります。

program.go

package main 

import (
    "fmt" 
    "os" 
) 

// input gets an array from the user. 
func input(in *os.File) (m int, array []int) { 
    if in == nil { 
     in = os.Stdin 
    } 

    fmt.Print("Enter the size of the array, n, and the difference, m: ") 
    var n int 
    _, err := fmt.Fscanf(in, "%d %d", &n, &m) 
    if err != nil { 
     panic(err) 
    } 

    fmt.Print("Enter the array as a space seperated string: ") 
    array = make([]int, n) 
    for i := 0; i < n; i++ { 
     _, _ = fmt.Fscan(in, &array[i]) 
    } 

    return m, array 
} 

func main() { 
    m, array := input(nil) 
    fmt.Println(m, array) 
} 

program_test.go

package main 

import (
    "fmt" 
    "io" 
    "io/ioutil" 
    "os" 
    "testing" 
) 

func TestInput(t *testing.T) { 
    var (
     n, m int 
     array []int 
    ) 

    in, err := ioutil.TempFile("", "") 
    if err != nil { 
     t.Fatal(err) 
    } 
    defer in.Close() 

    _, err = io.WriteString(in, "4 5\n"+"1 2 3 4\n") 
    if err != nil { 
     t.Fatal(err) 
    } 

    _, err = in.Seek(0, os.SEEK_SET) 
    if err != nil { 
     t.Fatal(err) 
    } 

    n, array = input(in) 
    if n != 5 || fmt.Sprintf("%v", array) != fmt.Sprintf("%v", []int{1, 2, 3, 4}) { 
     t.Error("unexpected results:", n, m, array) 
    } 
} 

出力:

$ go test 
ok  command-line-arguments 0.010s 
+0

ありがとう、私はバグを修正し、あなたの投稿に編集を提出しました。 – dmikalova

-5

できません。少なくともそれほど容易ではないので、努力する価値があるだろう。

+2

それが何らかの形でテストが可能になるように、そして、どのように私は自分のコードを変更することができますか? – dmikalova

+0

それはできません。基本的には、fmt.Scanfに対して単体テストを書くことはできません。あなたのコードを分割する必要があります:1)入力を取得します。 2)入力を処理します。上記の例では、1)os.Sile(os.Stdinかもしれない)と2)これを操作するinput()関数を使ってこの分割を行います。しかしメモ:ピーターによる答えは巧妙なものですが、入力がfmt.Fscanfによって読み込まれるので、fmt.Scanfが動作することを確認する* NOT *チェックはしません。 (私はそれが単なるラッパーであることを知っています)。私はまだ保持しています:あなたはユーザーの入力に対してユニットテストを書くことはできません。 – Volker

+0

あなたは何を言っているのですか.PeterSOの解決策は、Go自身が期待どおりに動作すると仮定する限り機能的に同等です。 peterSOの解決策も私の問題を正確に解決していますが、矛盾は私の質問に適切に言えないことが原因です。 – dmikalova

関連する問題