php editor Youzi introduces you how to test nested input in Go. When writing Go code, you often encounter situations where you need to handle nested input, such as nested JSON data or multi-dimensional arrays. How to effectively test these nested inputs is a key issue. This article will show you some practical methods and techniques to help you easily test nested inputs in Go and ensure the correctness and stability of your code. Whether you are a beginner or an experienced developer, these tips will be very helpful when writing and testing Go code. Let’s find out together!
I have the function of using os.stdin
to obtain user input
func (i input) getinput(stdin io.reader) (string, error) { reader := bufio.newreader(stdin) data, err := reader.readstring('\n') if err != nil { return "", fmt.errorf("get input error: %w", err) } return strings.replaceall(data, "\n", ""), nil }
In my program, I need to have 2 inputs:
name,err := getinput(os.stdin) if err != nil { // error handling..... } switch name { case "test": //do something... age, err := getinput(os.stdin) if err != nil { // error handling..... } fmt.println(age) case "another": // here another input }
Is it possible to write a unit test for this situation? To test a user input, I used this code snippet and it worked:
var stdin bytes.Buffer stdin.Write([]byte(fmt.Sprintf("%s\n", tt.input))) GetInput(stdin)
But it doesn't work with 2 nested inputs
Maybe consider using a function that returns a specific type of result and putting it into a separate package.
Since I see name
and age
mentioned, maybe we can assume a concrete type such as person
to illustrate.
Note that we want to include the actual reader as a parameter, rather than having a hardcoded reference to os.stdin
. This makes simulation of nested inputs possible in the first place.
In this way, the signature of the method might look like this:
func nestedinput(input io.reader) (*person, error)
The corresponding type can be:
type person struct { name string age int }
If you now merged your code snippets into a complete go file, in a separate directory with the name input.go
, it might look like this:
package input import ( "bufio" "fmt" "io" "strconv" "strings" ) func getinput(reader *bufio.reader) (string, error) { data, err := reader.readstring('\n') if err != nil { return "", fmt.errorf("get input error: %w", err) } return strings.replaceall(data, "\n", ""), nil } type person struct { name string age int } func nestedinput(input io.reader) (*person, error) { reader := bufio.newreader(input) name, err := getinput(reader) if err != nil { return nil, err } switch name { case "q": return nil, nil default: agestr, err := getinput(reader) if err != nil { return nil, err } age, err := strconv.atoi(agestr) if err != nil { return nil, err } return &person{name: name, age: age}, nil } }
q
returns nil, nil
and can be used to terminate the input, for example if the query is made in a loop.
unit test
unit test
func test_nestedinput(t *testing.t)
A file named input_test.go
should now provide the input data.
Since the nestedinput
function now requires io.reader
as a parameter, we can simply generate the required input, e.g.
input := strings.newreader("george\n26\n")
So the test might look like this:
package input import ( "strings" "testing" ) func Test_nestedInput(t *testing.T) { input := strings.NewReader("George\n26\n") person, err := NestedInput(input) if err != nil { t.Error("nested input failed") } if person == nil { t.Errorf("expected person, but got nil") return } if person.Name != "George" { t.Errorf("wrong name %s, expected 'George'", person.Name) } if person.Age != 26 { t.Errorf("wrong age %d, expected 26", person.Age) } }
Of course, the test can be extended with more details. However, as you can see, this simulates nested input.
The above is the detailed content of How to test nested input in Go. For more information, please follow other related articles on the PHP Chinese website!