模拟一个 go-logr 并验证它记录的消息。

huangapple go评论89阅读模式
英文:

Mock a go-logr and verify the message it logs?

问题

我正在使用go-logr/logr库。我有一个测试需要将logger作为参数传递,并检查它是否能够记录发送的数据。

我需要测试GetConfig函数:

config, err := GetConfig(FilePath, "ns", logger, "test")

最后,我需要在测试中打印来自logger的一些消息:

Expect(logger.msg).To(Equal("test"))

我的问题是如何进行模拟?

我尝试了以下方法,但没有成功:

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() {
        tl := NewTestLogger()
        config, err := GetConfig(kcfgFilePath, "ns", tl, "test")

但我无法打印logger的值,我应该如何正确地做呢?

类似于:

assert.Contains(t, tl.sink.Output, "test")

我应该使用testing包吗?

更新

这是一个没有断言的可工作版本。不确定我错过了什么,因为我想断言来自GetConfig的输出中的数据'tl'的键和值。

这是我在生产环境中的代码,我该如何使其工作?
https://go.dev/play/p/XDDkNjkESUw

我的问题是如何断言以下内容

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

我能够获取数据,但不确定如何断言值。

英文:

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

答案1

得分: 2

logr.New函数接受任何实现LogSink接口的对象 - 这意味着你只需要实现一个将调用保存到内存中的切片的对象,而不是打印输出,然后你可以期望该切片包含你的日志输出。

package main

import (
    "testing"
    "github.com/stretchr/testify/assert"
    // ... 一些额外的导入
)

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") // 你也可以测试输出的内容
}
英文:

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
}

huangapple
  • 本文由 发表于 2022年3月9日 04:53:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/71401299.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定