fmt.Printf
会打印到标准输出,用测试框架来捕获它会非常困难。fmt.Printf
的源码,你可以发现一种引入(hook in)的方式:Printf
内部,只是传入 os.Stdout
,并调用了 Fprintf
。os.Stdout
究竟是什么?Fprintf
期望第一个参数传递过来什么?io.Writer
是:io.Writer
是一个很好的通用接口,用于「将数据放在某个地方」。Writer
来把问候发送到某处。我们现在来使用这个抽象,让我们的代码可以测试,并且重用性更好。bytes
包中的 buffer
类型实现了 Writer
接口。Writer
,接着调用了 Greet
后,我们可以用它来检查写入了什么。Hello, Chris di_test.go:16: got '' want 'Hello, Chris'
name
,不过它传到了标准输出。writer
把问候发送到我们测试中的缓冲区。记住 fmt.Fprintf
和 fmt.Printf
一样,只不过 fmt.Fprintf
会接收一个 Writer
参数,用于把字符串传递过去,而 fmt.Printf
默认是标准输出。bytes.Buffer
的指针。这在技术上是正确的,但却不是很有用。Greet
函数接入到一个 Go 应用里面,其中我们会打印到标准输出。fmt.Fprintf
允许传入一个 io.Writer
接口,我们知道 os.Stdout
和 bytes.Buffer
都实现了它。io.Writer
,我们还可以将数据写入哪些地方?我们的 Greet
函数的通用性怎么样了?http.ResponseWriter
和用于创建请求的 http.Request
。在你实现服务器时,你使用 writer
写入了请求。http.ResponseWriter
也实现了 io.Writer
,所以我们可以重用处理器中的 Greet
函数。io.Writer
接口,我们可以用测试中的 bytes.Buffer
来作为 Writer
,然后我们可以使用标准库中的其它的 Writer
,在命令行应用或 web 服务器中使用这个函数。