【问题标题】:Mock a stdout stream for bufio.NewScanner模拟 bufio.NewScanner 的标准输出流
【发布时间】:2016-07-25 09:03:07
【问题描述】:

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

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

我怎样才能简明扼要地模拟它?

【问题讨论】:

  • stdout 上使用bufio.NewScanner 是什么意思?您是否正在使用 stdout 创建新的扫描仪?
  • @abhink 是 bufio.NewScanner(os.Stdout)

标签: testing go io mocking stdout


【解决方案1】:

要简单地测试您的代码,您可以使用@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 调用其阅读器的(输入到NewScannerRead 方法,直到它收到EOF 或错误。为简单起见,RRead 方法在第一次调用时将其数据复制到调用者的缓冲区 (p),并为任何后续调用返回一个 EOF

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

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

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

【讨论】:

  • 感谢您的详细解释,这很有意义!
【解决方案2】:

您可以使用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())
    }
}

【讨论】:

    猜你喜欢
    • 2013-02-16
    • 2014-08-23
    • 1970-01-01
    • 1970-01-01
    • 2011-07-17
    • 1970-01-01
    • 2012-08-22
    • 2012-08-03
    • 1970-01-01
    相关资源
    最近更新 更多