填充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

回到顶部