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() 함수를 사용하여이 작업을 수행합니다. 그러나 참고 : Peter의 대답은 영리한 대답이지만 fmt.Scanf가 입력을 읽을 때 fmt.Scanf가 작동하는지 확인하지는 않습니다. (나는 그것이 단지 포장지라는 것을 알고있다). 나는 아직 잡고있다. 사용자 입력에 대한 단위 테스트를 작성할 수 없다. – Volker

+0

나는 당신이 말하는 것을 얻지 만, 피터 SO의 해결책은 Go 자신이 예상대로 작동한다고 가정하면 기능적으로 동일하다. 피터 SO의 솔루션은 또한 정확하게 내 문제를 해결하고, 모든 불일치는 내 질문에 적절히 말로 표현할 수 없다는 전적으로 문제가 있습니다. – dmikalova

관련 문제