我想测试一个简单的函数:
func (t *Thing) print(min_verbosity int, message string) {
if t.verbosity >= minv {
fmt.Print(message)
}
}
但是如何测试函数实际发送到标准输出的内容呢?Test::Output在Perl中做了我想做的事情。我知道我可以编写自己的样板文件来在Go中做同样的事情(如here所述):
orig = os.Stdout
r,w,_ = os.Pipe()
thing.print("Some message")
var buf bytes.Buffer
io.Copy(&buf, r)
w.Close()
os.Stdout = orig
if(buf.String() != "Some message") {
t.Error("Failure!")
}
但每一项测试都有很多额外的工作。我希望有一个更标准的方法,或者一个抽象库来处理这个问题。
4条答案
按热度按时间mxg2im7a1#
还有一件事要记住,没有什么能阻止你编写函数来避免样板文件。
例如,我有一个使用
log
的命令行应用程序,我写了这个函数:然后像这样使用它:
使用这个assert库:http://godoc.org/github.com/stretchr/testify/assert。
von4xj4u2#
你可以做三件事之一。第一个是使用示例。
该包还运行并验证示例代码。示例函数可以包括以“Output:”开始的结束行注解,并且当运行测试时与函数的标准输出进行比较。(比较忽略前导和尾随空格。)以下是示例的示例:
第二种(更合适的,IMO)是为IO使用假函数。在你的代码中,你可以:
在你的测试中:
第三种是将
fmt.Fprintf
与io.Writer
一起使用,在生产代码中是os.Stdout
,但在测试中是bytes.Buffer
。t1rydlwq3#
您可以考虑向函数添加return语句,以返回实际打印出来的字符串。
现在,您的测试可以只检查返回的字符串与预期的字符串(而不是打印输出)。也许更符合测试驱动开发(TDD)。
而且,在您的产品代码中,不需要做任何更改,因为如果您不需要函数的返回值,您不必为其赋值。
aiqt4smr4#
将@Caleb的答案改编为testing和stdout,并从OP的代码中进行了一些修复:
注意
Close()
的位置。在我将其移动到ReadAll()
之上之前,读取操作会挂起并导致测试错误,原因很明显(等待更多输入)。