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

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

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

问题

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

我需要测试GetConfig函数:

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

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

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

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

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

  1. func NewTestLogger() logr.Logger {
  2. l := &testlogger{
  3. Formatter: funcr.NewFormatter(funcr.Options{}),
  4. }
  5. return logr.New(l)
  6. }
  7. var _ = Describe("test action", func() {
  8. It("action configuration with logger", func() {
  9. tl := NewTestLogger()
  10. config, err := GetConfig(kcfgFilePath, "ns", tl, "test")

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

类似于:

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

我应该使用testing包吗?

更新

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

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

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

  1. assert.Contains(t, tl.GetSink().WithName("Output"), "test")
  2. assert.Contains(t, tl.GetSink().WithName("Output"), "message")
  3. 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:

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

At the end I need to print some message from the logger in the test

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

My question is how should mock it?

I’ve tried with the following but without success

  1. func NewTestLogger() logr.Logger {
  2. l := &testlogger{
  3. Formatter: funcr.NewFormatter(funcr.Options{}),
  4. }
  5. return logr.New(l)
  6. }
  7. var _ = Describe(“test action, func() {
  8. It("action configuration with logger", func() {
  9. //var t *testing.T
  10. tl := NewTestLogger()
  11. config, err := GetConfig(kcfgFilePath, "ns", tl, "test")

But Im not able to print the value from the logger, how can I do it right?

  1. 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

  1. assert.Contains(t, tl.GetSink().WithName("Output"), "test")
  2. assert.Contains(t, tl.GetSink().WithName("Output"), "message")
  3. 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接口的对象 - 这意味着你只需要实现一个将调用保存到内存中的切片的对象,而不是打印输出,然后你可以期望该切片包含你的日志输出。

  1. package main
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. // ... 一些额外的导入
  6. )
  7. type TestLogger struct {
  8. Output map[string]map[int][]interface{}
  9. r RuntimeInfo
  10. }
  11. func (t *TestLogger) doLog(level int, msg string, keysAndValues ...interface{}) {
  12. m := make(map[int][]interface{}, len(keysAndValues))
  13. m[level] = keysAndValues
  14. t.output[msg] = m
  15. }
  16. func (t *TestLogger) Init(info RuntimeInfo) { t.r = info}
  17. func (t *TestLogger) Enabled(level int) bool {return true}
  18. func (t *TestLogger) Info(level int, msg string, keysAndValues ...interface{}) { t.doLog(level, msg, keysAndValues...) }
  19. func (t *TestLogger) Error(err error, msg string, keysAndValues ...interface{}) { t.doLog(level, msg, append(keysAndValues, err)...) }
  20. func (t *TestLogger) WithValues(keysAndValues ...interface{}) LogSink { return t}
  21. func (t *TestLogger) WithName(name string) LogSink { return t }
  22. func TestLoggerHasOutput(t *testing.T) {
  23. l := &TestLogger{make(map[string]map[int][]interface[]), RuntimeInfo{1}}
  24. tl := logr.New(l)
  25. config, err := GetConfig(kcfgFilePath, "ns", tl, "test")
  26. assert.Contains(t, l.Output, "ns") // 你也可以测试输出的内容
  27. }
英文:

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.

  1. package main
  2. import (
  3. "testing"
  4. "github.com/stretchr/testify/assert"
  5. // ... some extra imports
  6. )
  7. type TestLogger struct {
  8. Output map[string]map[int][]interface{}
  9. r RuntimeInfo
  10. }
  11. func (t *TestLogger) doLog(level int, msg string, keysAndValues ...interface{}) {
  12. m := make(map[int][]interface{}, len(keysAndValues))
  13. m[level] = keysAndValues
  14. t.output[msg] = m
  15. }
  16. func (t *TestLogger) Init(info RuntimeInfo) { t.r = info}
  17. func (t *TestLogger) Enabled(level int) bool {return true}
  18. func (t *TestLogger) Info(level int, msg string, keysAndValues ...interface{}) { t.doLog(level, msg, keysAndValues...) }
  19. func (t *TestLogger) Error(err error, msg string, keysAndValues ...interface{}) { t.doLog(level, msg, append(keysAndValues, err)...) }
  20. func (t *TestLogger) WithValues(keysAndValues ...interface{}) LogSink { return t}
  21. func (t *TestLogger) WithName(name string) LogSink { return t }
  22. func TestLoggerHasOutput(t *testing.T) {
  23. l := &TestLogger{make(map[string]map[int][]interface[]), RuntimeInfo{1}}
  24. tl := logr.New(l)
  25. config, err := GetConfig(kcfgFilePath, "ns", tl, "test")
  26. assert.Contains(t, l.Output, "ns") // you can also test the contents of the output as well
  27. }

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:

确定