Testing Logged Output in Go Tests
In Go, unit tests often involve verifying the output or logs generated by the tested function. Suppose we have a function that logs errors in certain scenarios.
The Problem:
Given the following function readByte that logs an error message:
func readByte(/*...*/) { // ... if err != nil { fmt.Println("ERROR") log.Print("Couldn't read first byte") return } // ... }
How can we test the output error in readByte using a go test without modifying the function itself?
The Solution:
To capture the log output, we can redirect the output of the log package to a temporary buffer during the test and then assert the contents of the buffer.
Example Code:
In the readbyte_test.go file:
package main import ( "bytes" "fmt" "io" "log" "os" "testing" ) func readByte( /*...*/ ) { // ... err := io.EOF // Force an error if err != nil { fmt.Println("ERROR") log.Print("Couldn't read first byte") return } // ... } func TestReadByte(t *testing.T) { var buf bytes.Buffer log.SetOutput(&buf) defer func() { log.SetOutput(os.Stderr) }() readByte() t.Logf("Output: %s", buf.String()) }
Example Output:
$ go test -v readbyte_test.go === RUN TestReadByte --- PASS: TestReadByte (0.00s) readbyte_test.go:30: Output: ERROR Couldn't read first byte PASS ok command-line-arguments 0.004s $
In this example, the outputting error messages can now be tested and verified using Go's built-in testing tools without altering the original readByte function.
The above is the detailed content of How to Test Logged Output in Go Tests Without Modifying the Function?. For more information, please follow other related articles on the PHP Chinese website!