模拟 bufio.NewScanner 的标准输出流

Mock a stdout stream for bufio.NewScanner

我想为使用 bufio.NewScannerScan() 的效用函数编写测试。我通常在 stdout 上使用它,现在我想模拟一小段流,在那里我可以 return 一些静态字符串以进行测试。

bufio.NewScanner(r io.Reader) 采用 Reader 但这只需要 read 方法。通过阅读源代码,我无法弄清楚它从哪个缓冲区读取或如何传入。

我怎样才能简明扼要地嘲笑它?

您可以使用 bytes.Buffer,因为它实现了 io.Reader 功能。

例子 https://play.golang.org/p/gjjMmT3SzD:

package main

import (
    "bufio"
    "bytes"
    "fmt"
)

func main() {
    buf := bytes.NewBufferString("foo\nbar")
    scanner := bufio.NewScanner(buf)
    for scanner.Scan() {
        fmt.Println(scanner.Text())
    }
}

要简单地测试您的代码,您可以使用@Sven 的回答。

要了解用于测试的简单 io.Reader,请考虑以下示例:

type R struct {
    Data string
    done bool
}

func (r *R) Read(p []byte) (n int, err error) {
    copy(p, []byte(r.Data))
    if r.done {
        return 0, io.EOF
    }
    r.done = true
    return len([]byte(r.Data)), nil
}

R 是一种自定义测试类型,它通过 Read 方法实现了 io.Reader 接口。因此,它将被 NewScanner 接受。它可以用作:

func NewR(data string) *R {
    return &R{data, false}
}

r := NewR("Test\nmessage\n")
scanner := bufio.NewScanner(r)

for scanner.Scan() {
    fmt.Printf("Line: %s\n", scanner.Text())
}

输出:

Line: Test 
Line: message

类型 R 和它的 Read 方法都被定义为一个简单的字节源。 Scan 调用其 reader 的(NewScanner 的输入)Read 方法,直到它收到 EOF 或错误。为简单起见,RRead 方法在其第一次调用中将其数据复制到调用者的缓冲区 (p),并在任何后续调用中将 returns 复制到 EOF

请注意,\n 处的行的实际拆分是由 scanner.Scan 而不是 r.Read 完成的。

您可以修改上面的 Read 方法以根据您的要求获得自定义行为。

工作示例:https://play.golang.org/p/zqDoQDIE93