模拟 bufio.NewScanner 的标准输出流

Mah*_*oni 1 testing io stdout mocking go

我想为我使用bufio.NewScanner和的实用程序编写一个测试Scan()。我通常使用它stdout,现在我想模拟一小段流,我可以在其中返回一些静态字符串以进行测试。

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

我怎样才能以简短而简洁的方式嘲笑它?

abh*_*ink 5

要简单地测试您的代码,您可以使用@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
}
Run Code Online (Sandbox Code Playgroud)

R是一种自定义测试类型,io.Reader通过Read方法实现接口。因此,它将被 接受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())
}
Run Code Online (Sandbox Code Playgroud)

输出:

Line: Test 
Line: message
Run Code Online (Sandbox Code Playgroud)

类型R及其Read方法都被定义为一个简单的字节源。Scan调用它的读取器(输入到NewScannerRead方法,直到它得到一个EOF或一个错误。为简单起见,RRead方法p在第一次调用时将其数据复制到调用者的缓冲区 ( ) 并EOF为任何后续调用返回。

请注意, at 行的实际拆分\n是由scanner.Scan和 not完成的r.Read

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

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