如何使用Go日志包glog测试代码?

时间:2016-12-20 16:41:25

标签: unit-testing go

我已经实现了一个包装glog的类型,这样我就可以在日志中添加一个前缀来识别我程序中日志的发射器,我可以更改每个发射器的日志级别。

我如何实施单元测试?问题是glog将文本输出到stdErr。

代码是微不足道的,但我希望有单元测试和100%覆盖,就像代码的其余部分一样。这种编程工作已经付出了代价。

2 个答案:

答案 0 :(得分:2)

测试哪个捕获stderr:

package main

import (
    "bytes"
    "io"
    "os"
    "testing"

    "github.com/golang/glog"
    "strings"
)

func captureStderr(f func()) (string, error) {
    old := os.Stderr // keep backup of the real stderr
    r, w, err := os.Pipe()
    if err != nil {
        return "", err
    }
    os.Stderr = w

    outC := make(chan string)
    // copy the output in a separate goroutine so printing can't block indefinitely
    go func() {
        var buf bytes.Buffer
        io.Copy(&buf, r)
        outC <- buf.String()
    }()

    // calling function which stderr we are going to capture:
    f()

    // back to normal state
    w.Close()
    os.Stderr = old // restoring the real stderr
    return <-outC, nil
}

func TestGlogError(t *testing.T) {
    stdErr, err := captureStderr(func() {
        glog.Error("Test error")
    })
    if err != nil {
        t.Errorf("should not be error, instead: %+v", err)
    }
    if !strings.HasSuffix(strings.TrimSpace(stdErr), "Test error") {
        t.Errorf("stderr should end by 'Test error' but it doesn't: %s", stdErr)
    }
}

运行测试:

go test -v
=== RUN   TestGlogError
--- PASS: TestGlogError (0.00s)
PASS
ok      command-line-arguments  0.007s

答案 1 :(得分:0)

编写描述您的用法的界面。如果你使用V方法,这将不是很漂亮,但你有一个包装器,所以你已经完成了修复所需的艰苦工作。

对于您需要测试的每个包,请定义

type Logger interface {
    Infoln(...interface{}) // the methods you actually use in this package
}

然后,您可以直接在代码中直接引用glog类型来轻松交换它。