You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为Go语言中的嵌套输入场景编写单元测试

问题

我有一个使用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
}

程序中需要实现两次输入逻辑:

  • 第一次获取基础信息(比如用户名)
  • 第二次获取依赖于首次输入的附加信息

核心业务逻辑如下:

name, err := GetInput(os.Stdin)
if err != nil {
    // 错误处理.....
}

switch name {
case "test":
    // 执行操作...
    age, err := GetInput(os.Stdin)
    if err != nil {
        // 错误处理.....
    }
    fmt.Println(age)

case "another":
    // 此处为另一个输入操作
}

我目前能通过以下代码测试单次用户输入场景:

var stdin bytes.Buffer
stdin.Write([]byte(fmt.Sprintf("%s\n", tt.input)))
GetInput(stdin)

但这种方法无法适配嵌套输入的测试场景,想问下是否能为这种嵌套输入的场景编写单元测试?

解决方案

完全可以实现嵌套输入场景的单元测试,核心思路是在模拟的bytes.Buffer中按输入顺序写入所有需要的内容,用换行符分隔每一次输入即可。因为bufio.Reader会按顺序读取缓冲区中的内容,每次调用ReadString('\n')都会读取到下一个换行符前的内容,刚好匹配多次输入的场景。

测试示例代码

针对name为test时需要输入age的场景,测试代码可以这么写:

import (
    "bytes"
    "fmt"
    "testing"
)

// 假设你的业务逻辑封装在一个函数里,比如HandleUserInput
func HandleUserInput(stdin io.Reader) {
    name, err := GetInput(stdin)
    if err != nil {
        return
    }

    switch name {
    case "test":
        age, err := GetInput(stdin)
        if err != nil {
            return
        }
        fmt.Println(age)
    case "another":
        // 其他逻辑
    }
}

func TestHandleUserInputWithNestedInput(t *testing.T) {
    // 模拟两次输入:第一次是"test",第二次是"25",用换行分隔
    var stdin bytes.Buffer
    stdin.WriteString("test\n25\n")

    // 调用业务逻辑函数,传入模拟的输入
    HandleUserInput(&stdin)

    // 若需验证输出,可重定向os.Stdout到bytes.Buffer,读取后断言结果
}

关键说明

  • 模拟输入时,必须按实际交互顺序写入内容,每个输入后加换行符\n,和用户终端输入行为一致。
  • 测试不同分支(比如name为another的场景)时,只需调整缓冲区内容,例如写入another\nxxx\n。
  • 如需验证输出结果,可通过重定向os.Stdout到bytes.Buffer,读取缓冲区内容做断言。

内容的提问来源于stack exchange,提问作者Vlad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 11:45:32