Im using the following go-logr/logr
library.
I have a test which needs to pass the logger as parameter
and check that it was able to log the data that was sent.
I need to test the function GetConfig
:
config, err := GetConfig(FilePath, "ns", logger, "test" )
At the end I need to print some message from the logger in the test
Expect(logger.msg).To(Equal("test"))
My question is how should mock it?
I’ve tried with the following but without success
func NewTestLogger() logr.Logger {
l := &testlogger{
Formatter: funcr.NewFormatter(funcr.Options{}),
}
return logr.New(l)
}
var _ = Describe(“test” action, func() {
It("action configuration with logger", func() {
//var t *testing.T
tl := NewTestLogger()
config, err := GetConfig(kcfgFilePath, "ns", tl, "test")
But Im not able to print the value from the logger, how can I do it right?
Something like
assert.Contains(t, tl.sink.Output, "test")
Should I use the testing package? update
This is a working version without the assertion.
Not sure what I miss there as I want to assert the data that are coming from the output of the GetConfig
'tl` and get the key and value
This is close to the code I've in prod, how can I make work? https://go.dev/play/p/XDDkNjkESUw
My Question is how should I assert the following
assert.Contains(t, tl.GetSink().WithName("Output"), "test")
assert.Contains(t, tl.GetSink().WithName("Output"), "message")
assert.Contains(t, tl.GetSink().WithName("Output"), "print something")
I was able to get the data like following, but not sure how to assert the values
CodePudding user response:
The logr.New
function accepts any implementation of the LogSink interface - This means you should just implement one that saves the calls onto a slice in-memory instead of printing, and then you can expect that the slice has your log output.
package main
import (
"testing"
"github.com/stretchr/testify/assert"
// ... some extra imports
)
type TestLogger struct {
Output map[string]map[int][]interface{}
r RuntimeInfo
}
func (t *TestLogger) doLog(level int, msg string, keysAndValues ...interface{}) {
m := make(map[int][]interface{}, len(keysAndValues))
m[level] = keysAndValues
t.output[msg] = m
}
func (t *TestLogger) Init(info RuntimeInfo) { t.r = info}
func (t *TestLogger) Enabled(level int) bool {return true}
func (t *TestLogger) Info(level int, msg string, keysAndValues ...interface{}) { t.doLog(level, msg, keysAndValues...) }
func (t *TestLogger) Error(err error, msg string, keysAndValues ...interface{}) { t.doLog(level, msg, append(keysAndValues, err)...) }
func (t *TestLogger) WithValues(keysAndValues ...interface{}) LogSink { return t}
func (t *TestLogger) WithName(name string) LogSink { return t }
func TestLoggerHasOutput(t *testing.T) {
l := &TestLogger{make(map[string]map[int][]interface[]), RuntimeInfo{1}}
tl := logr.New(l)
config, err := GetConfig(kcfgFilePath, "ns", tl, "test")
assert.Contains(t, l.Output, "ns") // you can also test the contents of the output as well
}