Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write tests against user input in Go

Tags:

input

go

How would I test against user input from fmt.Scan/Scanf/Scanln?

For example how could I test that the function input will accept "4 5\n" and "1 2 3 4\n" from STDIN and return n == 5 and 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)
}
like image 203
dmikalova Avatar asked Jul 03 '13 19:07

dmikalova


People also ask

Where do you put tests in go?

The convention for naming test files in Go is to end the file name with the _test.go suffix and place the file in the same directory as the code it tests. In the example above, the Multiply function is in integers.go , so its tests are placed in integers_test.go .

How do I run a test case in Golang?

go test : to run all _test.go files in the package. go test -v : will display the result of all test cases with verbose logging. go test -run TestFunctionName/Inputvalue= : to run the test case for specific input.


1 Answers

Here's a very rough draft to illustrate the principle.

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

Output:

$ go test
ok      command-line-arguments  0.010s
like image 169
peterSO Avatar answered Sep 19 '22 01:09

peterSO