填充os.Stdin以读取其中的函数
如何在我的测试中填写os.Stdin中使用扫描仪从中读取的功能?
我要求使用以下功能通过扫描仪输入用户命令行:
func userInput() error { scanner := bufio.NewScanner(os.Stdin)
println("What is your name?")
scanner.Scan()
username = scanner.Text()
/* ... */
}
现在如何测试这种情况并模拟用户输入?以下示例不起作用。Stdin还是空的。
func TestUserInput(t *testing.T) { var file *os.File
file.Write([]byte("Tom"))
os.Stdin = file
err := userInput()
/* ... */
}
回答:
嘲笑 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
简单,首选的方式
另请注意,您可以重构userInput()
为不读取os.Stdin
,但是可以接收io.Reader
到读取的内容。这将使它更健壮并且更容易测试。
在您的应用程序,你可以简单地传递os.Stdin
给它,并在测试中,你可以通过任何io.Reader
它创建/在测试准备,例如使用strings.NewReader()
,bytes.NewBuffer()
或bytes.NewBufferString()
。
以上是 填充os.Stdin以读取其中的函数 的全部内容, 来源链接: utcz.com/qa/423288.html