Kerningham's Book的第11章为这个问题提供了一个很好的解决方案.诀窍是将对fmt.Printline()的调用更改为对fmt.Fprint(out,...)的调用,其中out被初始化为os.Stdout
这可以在测试工具中覆盖到new(bytes.Buffer),允许测试捕获输出.
请参阅https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo.go和 https://github.com/adonovan/gopl.io/blob/master/ch11/echo/echo_test .走
由OP ... sample.go编辑:
package main import( "fmt" "os" "io" ) var out io.Writer = os.Stdout // modified during testing var exit func(code int) = os.Exit type sample struct { value int64 } func (s sample) useful() { if s.value == 0 { fmt.Fprint(out, "Error: something is wrong!\n") exit(1) } else { fmt.Fprint(out, "May the force be with you!\n") } } func main() { s := sample{42} s.useful() s.value = 0 s.useful() } // output: // May the force be with you! // Error: this is broken and not useful! // exit status 1
cli_test.go:
package main import( "bytes" "testing" ) func TestUsefulPositive(t *testing.T) { bak := out out = new(bytes.Buffer) defer func() { out = bak }() s := sample{42} s.useful() if out.(*bytes.Buffer).String() != "May the force be with you!\n" { t.Fatal("There is something wrong with the CLI") } } func TestUsefulNegative(t *testing.T) { bak := out out = new(bytes.Buffer) defer func() { out = bak }() code := 0 osexit := exit exit = func(c int) { code = c } defer func() { exit = osexit }() s := sample{0} s.useful() if out.(*bytes.Buffer).String() != "Error: something is wrong!\n" { t.Fatal("There is something wrong with the CLI") } if code != 1 { t.Fatal("Wrong exit code!") } }