如何在golang中测试打印到控制台的方法?

I have next struct.

package logger

import "fmt"

type IPrinter interface {
    Print(value string)
}

type ConsolePrinter struct{}

func (cp *ConsolePrinter) Print(value string) {
    fmt.Printf("this is value: %s", value)
}

Test coverage says I need to test that ConsolePrinter Print method.

How can I cover this method?

Thanks.

Use Examples to convey the usage of a function.

Don't fret over 100% test coverage, especially for simple straightforward functions.

func ExampleHello() {
    fmt.Println("hello")
    // Output: hello
}

The additional benefit is that examples are outputted in a generated doc with go doc tool.

Following comment that @icza wrote, I've written test below.

func TestPrint(t *testing.T) {
    rescueStdout := os.Stdout
    r, w, _ := os.Pipe()
    os.Stdout = w

    cp := &ConsolePrinter{}
    cp.Print("test")

    w.Close()
    out, _ := ioutil.ReadAll(r)
    os.Stdout = rescueStdout

    if string(out) != "this is value: test" {
        t.Errorf("Expected %s, got %s", "this is value: test", out)
    }
}

I've found example in question What is the best way to convert byte array to string?.

I would recommend to create new instance of the logger, which would behave exactly as fmt methods for printing data to console. Also, you can configure it with additional features like showing the filename, date and etc. Such custom logger can be passed as a parameter to your service/instance factory method. That would make it really easy to mock and test.

Your code

type Logs interface {
    Println(v ...interface{})
}

type InstanceToTest struct {
    log Logs
}

func InstanceToTestFactory(logger Logs) *InstanceToTest {
    return &InstanceToTest{logger}
}

func (i *InstanceToTest) SomeMethod(a string) {
    i.log.Println(a)
}

Create a mock for logger

type LoggerMock struct {
    CalledPrintln []interface{}    
}

func (l *LoggerMock) Println(v ...interface{}) {
    l.CalledPrintln = append(CalledPrintln, v)
}

And in your test

func TestInstanceToTestSomeMethod(t *testing.T) {
    l := &LoggerMock{}
    i := InstanceToTestFactory(l)
    a := "Test"

    i.SomeMethod(a)

    if len(l.CalledPrintln) == 0 || l.CalledPrintln[0] != a {
        t.Error("Not called")
    }
}