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