填充 os.Stdin 作为从中读取的函数

2023-12-01

如何在测试中填写 os.Stdin 以使用扫描仪读取其中的函数?

我使用以下函数通过扫描仪请求用户命令行输入:

func userInput() error {
    scanner := bufio.NewScanner(os.Stdin)

    println("What is your name?")
    scanner.Scan()
    username = scanner.Text()

    /* ... */
}

现在我该如何测试这个案例并模拟用户输入? 以下示例不起作用。标准输入仍然是空的。

func TestUserInput(t *testing.T) {
    var file *os.File
    file.Write([]byte("Tom"))
    os.Stdin = file

    err := userInput()
    /* ... */
}

Mocking os.Stdin

你走在正确的轨道上os.Stdin是一个变量(类型*os.File),您可以修改它,您可以在测试中为其分配新值。

最简单的是创建一个临时文件,其中包含要模拟的内容作为输入os.Stdin。要创建临时文件,请使用ioutil.TempFile()。然后将内容写入其中,并返回到文件的开头。现在您可以将其设置为os.Stdin并执行您的测试。不要忘记清理临时文件。

我修改了你的userInput()对此:

func userInput() error {
    scanner := bufio.NewScanner(os.Stdin)

    fmt.Println("What is your name?")
    var username string
    if scanner.Scan() {
        username = scanner.Text()
    }
    if err := scanner.Err(); err != nil {
        return err
    }

    fmt.Println("Entered:", username)
    return nil
}

这是测试它的方法:

func TestUserInput(t *testing.T) {
    content := []byte("Tom")
    tmpfile, err := ioutil.TempFile("", "example")
    if err != nil {
        log.Fatal(err)
    }

    defer os.Remove(tmpfile.Name()) // clean up

    if _, err := tmpfile.Write(content); err != nil {
        log.Fatal(err)
    }

    if _, err := tmpfile.Seek(0, 0); err != nil {
        log.Fatal(err)
    }

    oldStdin := os.Stdin
    defer func() { os.Stdin = oldStdin }() // Restore original Stdin

    os.Stdin = tmpfile
    if err := userInput(); err != nil {
        t.Errorf("userInput failed: %v", err)
    }

    if err := tmpfile.Close(); err != nil {
        log.Fatal(err)
    }
}

运行测试,我们看到输出:

What is your name?
Entered: Tom
PASS

另请参阅有关模拟文件系统的相关问题:在 Golang 中测试文件系统的示例代码

最简单、首选的方式

另请注意,您可以重构userInput()不读os.Stdin,但它可能会收到一个io.Reader从中读取。这将使它更加健壮并且更容易测试。

在您的应用程序中,您可以简单地传递os.Stdin到它,并且在测试中你可以通过任何io.Reader在测试中创建/准备它,例如使用strings.NewReader(), bytes.NewBuffer() or bytes.NewBufferString().

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

填充 os.Stdin 作为从中读取的函数 的相关文章

随机推荐

  • Oracle SQL:如何显示空周/没有数据的周?

    如同这个问题 但我的数据集还有一个包含许多 ID 的附加列 每个 ID 都有一个按恒定时间范围回溯的数据集 并且某些周可能会丢失数据 我想填写丢失周的值 例如 我想要这个 ID WEEKEND DAY VALUE A00 2012 01 0
  • Android USBHost 模式 - 为什么我的 IRDA 设备在 ClaimInterface 上失败?

    我的 Xperia Neo Cyanogen Mod 9 连接了一个 Lindy IRDA USB 桥接器 我已经更改了功能以支持主机模式等 代码中一切看起来都很好 我检测到该设备 我可以看到接口和两个端点 一进一出 但是一旦我尝试声明接口
  • 列表框(JList)不会从自定义 ListModel 动态更新

    我正在使用 Seesaw 在 Clojure 中开发 GUI 应用程序 并且在我的自定义 ListModel 更新时无法更新列表框 Java 中的 JList 这是我的一些代码 deftype ActionHistoryListModel
  • python 中多线程应用程序中的分段错误

    我在 python 中有一个多线程应用程序 其中我创建了多个生产者线程 它们从数据库中提取数据 数据以块的形式提取 因此 线程创建具有限制值的sql语句的部分被保留在锁内 为了让线程同时执行查询 query 函数被保留在锁之外 然后结果获取
  • C#/WPF - 我无法从后台工作人员更新 UI

    我有一个代码可以使用以下命令从特定 Twitter 帐户获取推文推特锐利库 创建自定义实例UserControl并发布推文UserControl然后将其添加到StackPanel 但是 我必须收到很多推文 并且在向应用程序添加用户控件时 应
  • 按自定义顺序按键对数组进行排序

    我有以下多维数组 June 2015 gt LOW gt 160 50 MEDIUM gt 0 00 HIGH gt 60 80 July 2015 gt MEDIUM gt 226 00 HIGH gt 263 00 LOW gt 121
  • 如何将日期格式从 YYYY/MM/DD 更改为 DD/MM/YYYY

    我有一列日期 读作character值 是的 它们应该是相同的 str df date date chr 30 08 2017 30 08 2017 30 08 2017 30 08 2017 然后我将这些值转换为Date format s
  • 复制到剪贴板,无需 Flash

    我找到了许多复制到剪贴板的解决方案 但它们要么带有闪存 要么用于网站端 我正在寻找自动复制到剪贴板的方法 无需闪存 对于用户端 它用于用户脚本 当然还有跨浏览器 如果没有 Flash 这在大多数浏览器中都是不可能的 用户的剪贴板是与安全相关
  • htaccess:删除 .php 扩展名

    我有一个名为 Show php 的文件 我想删除这个的 php 扩展名 如果有人请求 Show php 将他重定向到没有 php 扩展名的页面 这是我的 htaccess 但它不会将用户重定向到没有扩展名的页面 RewriteCond RE
  • 将字符串中的所有字母加 1 [关闭]

    Closed 这个问题需要多问focused 目前不接受答案 当我输入 abc 我想得到 bcd 作为输出 所以我想要A to be B and B to be C等等直到Z这将是A 那么我该怎么做呢 我一点也不知道 您可以使用transl
  • 如何修改 Elastislide 使其无限循环

    我一直在寻找一种图像轮播 它可以一次显示多个图像 具有响应能力并且可以无限循环 Elastislide 似乎是最合适的 http tympanus net Development Elastislide index2 html 我能找到的唯
  • 未捕获的类型错误:无法调用未定义的方法“请求”

    在我的 JavaScript 代码中 我不断收到以下错误 Uncaught TypeError Cannot call method request of undefined 我的 JavaScript 如下 任何帮助将不胜感激 myJso
  • 如何以(线程)安全的方式跟踪 TPL 管道中的故障项

    我正在使用 TPL 管道设计和 Stephen Cleary 的管道设计尝试库简而言之 它包装了值 异常并将其沿着管道浮动 因此 即使是在处理方法中抛出异常的项目 最后当我await resultsBlock Completion have
  • Pyplot:绘制一侧带有刻度的曲线

    我可以使用 matplotlib pyplot 中的plot 函数来绘制这样一侧有刻度的曲线吗 Upgrade根据答案here我可以扩展这个例子 def f x return x x np exp x x def get parameter
  • Ubuntu rake 中止了! NameError:未初始化的常量 ActionDispatch::XmlParamsParser

    我正在尝试在 16 04 ubuntu 的机器上安装 redmine 的插件 现在我正在尝试安装敏捷插件 我收到了有关如何安装插件的官方文档 我按照逐步安装的步骤进行操作 但遇到了错误 重要的 我正在使用 Ruby 2 3 1 Steps
  • NextJS 环境变量不起作用

    我已经研究这个问题至少一个小时了 到目前为止我还很困惑 也许我不理解文档或媒体文章 但是 据我了解 NextJS 我已经安装了最新版本 提供了一个内置的环境变量解决方案 所以 没有必要dotenv包裹 由于 NextJS 已设置 我需要做的
  • 我无法使用 subclipse 提交 .so 库文件

    这是一个 Android 应用程序 我在文件夹中添加了一个 so 本机库 库 armeabi libc so 但是 我无法将其提交到存储库 当我右键单击 提交 时 没有任何更改反映我添加了 so 本机库文件 我该如何解决这个问题 好的 我找
  • 向远程 WebDriver 服务器发送 URL 请求 - Chrome

    我正面临着向远程 WebDriver 服务器发送 URL 请求在 Chrome 中执行 selenium 脚本时出错 我使用 Selenium 与 C 和最新版本的 Chrome 驱动程序 Chrome 66 0 3359 181 和 Se
  • Swift 位数组到字节数组(UInt8 数组)

    我有位数组 var bits Bit 以及如何将其转换为字节数组 var bytes UInt8 例如 我有 280 位 字节数组中应该有 35 个 UInt8 我可以想到的解决方案是 我采用 8 位并检查第一个是否为真 第二个是否为真 等
  • 填充 os.Stdin 作为从中读取的函数

    如何在测试中填写 os Stdin 以使用扫描仪读取其中的函数 我使用以下函数通过扫描仪请求用户命令行输入 func userInput error scanner bufio NewScanner os Stdin println Wha