我有使用os.Stdin
获取用户输入的函数
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
}
在我的程序中,我需要有2个输入:
- 首先用于获取基本信息,例如用户名
- 第二个用于获取依赖于第一个输入的附加信息
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
}
有可能为这种情况编写单元测试吗?为了测试一个用户输入,我使用了以下代码片段,它工作正常:
var stdin bytes.Buffer
stdin.Write([]byte(fmt.Sprintf("%s\n", tt.input)))
GetInput(stdin)
但它不能处理2个嵌套输入
1条答案
按热度按时间py49o6xq1#
也许可以考虑使用一个返回特定类型结果的函数,并将其放入单独的包中。
因为我看到提到了
name
和age
,也许我们可以假设一个像Person
这样的具体类型来进行说明。需要注意的是,我们希望包含实际的reader作为参数,而不是硬编码引用
os.Stdin
,这使得模拟嵌套输入成为可能。这样,方法的签名可能类似于以下内容:
对应的类型可以是:
如果现在将代码片段合并为一个完整的GO文件,并将其命名为
input.go
,放在一个单独的目录中,则可能如下所示:q
的输入返回nil, nil
,并且可以用于终止输入,例如,如果查询是在循环中进行的。单元测试
单元测试
在名为
input_test.go
的文件中,现在应该提供输入数据。由于
NestedInput
函数现在需要一个io.Reader
作为参数,我们可以简单地生成所需的输入,例如,所以测试看起来像这样:
当然,测试还可以扩展更多的细节,但是正如您所看到的,这模拟了嵌套的输入。