我有一段代码设置os.Pipe
来捕获Stdout / Stderr:
// Capture executes f() and returns the captured data
func (s *stdcap) Capture(f func()) string {
s.mu.Lock()
defer s.mu.Unlock()
var old, r, w *os.File
if s.out {
old = os.Stdout
r, w, _ = os.Pipe()
os.Stdout = w
} else {
old = os.Stderr
r, w, _ = os.Pipe()
os.Stderr = w
}
f()
outC := make(chan string)
defer close(outC)
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
w.Close()
if s.out {
os.Stdout = old
} else {
os.Stderr = old
}
return <-outC
}
今天我尝试将此代码与log
包一起使用,但它不起作用。
这有效:
func TestOutCapture(t *testing.T) {
sc := StdoutCapture()
out := sc.Capture(func() {
fmt.Printf("Hello world!")
})
if out != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", out)
}
}
func TestErrCapture(t *testing.T) {
sc := StderrCapture()
err := sc.Capture(func() {
fmt.Fprintf(os.Stderr, "Hello world!")
})
if err != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", err)
}
}
这些不起作用:
func TestLogOutCapture(t *testing.T) {
sc := StdoutCapture()
log.SetOutput(os.Stdout)
out := sc.Capture(func() {
log.Printf("Hello world!")
})
if out != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", out)
}
}
func TestLogErrCapture(t *testing.T) {
sc := StderrCapture()
log.SetOutput(os.Stderr)
err := sc.Capture(func() {
log.Printf("Hello world!")
})
if err != "Hello world!" {
t.Errorf("Expected \"Hello world!\", got: %s\n", err)
}
}
关于我可以调试此问题的任何想法? Golang log
包不使用os.Stdout/os.Stderr
吗?
答案 0 :(得分:3)
日志记录包initializes the standard logger with the value os.Stderr
at initialization time。对变量os.Stderr
的修改不会更改logger field中的值。
调用log.SetOutput以从捕获函数更改标准记录器的输出位置。不幸的是,没有办法获得标准记录器的输出,因此您可以在捕获功能中保存和恢复它。