Home > Backend Development > Golang > How to test nested input in Go

How to test nested input in Go

王林
Release: 2024-02-14 12:00:11
forward
1005 people have browsed it

如何在 Go 中测试嵌套输入

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!

Question content

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
}

Copy after login

In my program, I need to have 2 inputs:

  • First used to obtain basic information, such as username
  • The second one is used to get additional information that depends on the first input
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
}
Copy after login

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)
Copy after login

But it doesn't work with 2 nested inputs

Workaround

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)
Copy after login

The corresponding type can be:

type person struct {
    name string
    age  int
}
Copy after login

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
    }
}
Copy after login
The input of

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)
Copy after login

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")
Copy after login

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)
    }
}
Copy after login

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!

source:stackoverflow.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template