2016-12-20 1 views
1

Ich habe ein Typ-Wrapping-Glog implementiert, so dass ich ein Präfix zur Protokollnachricht hinzufügen kann, die den Emitter des Protokolls in meinem Programm identifiziert, und ich kann die Protokollstufe pro Emitter ändern.Wie Test Code mit dem Go-Logging-Paket Glog?

Wie kann ich die Komponententests implementieren? Das Problem ist, dass Glog Text an stdErr ausgibt.

Der Code ist trivial, aber ich hätte gerne die Einheit Test und 100% Abdeckung wie der Rest des Codes. Dieser Programmieraufwand hat sich bereits bezahlt gemacht.

+0

Die glog Ausgang (wenn Sie beziehen sich auf [ 'github.com/golang/glog'](https:/ /godoc.org/github.com/golang/glog)) ist konfigurierbar. Könnten Sie lieber in Dateien als in stderr ausgeben? – JimB

+1

können Sie stderr im Test wie stdout erfassen, wird in diesem [Antwort] (http://stackoverflow.com/a/10476304/1024794) –

+0

@ JimB erfasst, das funktionieren würde. Aber, aber es wäre schwierig zu testen, was bei jedem Aufruf meiner Wrapper-Methoden ausgegeben wurde. – chmike

Antwort

2

-Test, die stderr erfasst:

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) 
    } 
} 

Lauftest:

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

Schreiben Sie eine Schnittstelle, die Ihre Verwendung beschreibt. Das wird nicht sehr schön sein, wenn Sie die Methode V verwenden, aber Sie haben einen Wrapper, so dass Sie bereits die harte Arbeit erledigt haben, die das zur Folge hätte.

Für jedes Paket, das Sie testen müssen, definieren

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

Und dann kann man es leicht von nicht-Typen fest tauscht im Code direkt Glog.

+1

Das habe ich schon gemacht. Dies ermöglicht es, die Verwendung meines Wrappers zu testen. Perfekter Vorschlag. Die Frage ist, wie man den Wrapper selbst testet. – chmike