【问题标题】:Asserting That Code Should Panic With Logrus Error断言代码应该出现 Logrus 错误
【发布时间】:2022-11-02 11:30:07
【问题描述】:

使用 logrus 时,如何使用 testify 之类的断言库断言 panic?

以下面的代码为例:

var mylogger = logrus.WithContext("MyLogger")

func LoadPreparedStatements() {
    db := psql.PsqlClient()
    var err error

    myPreparedStatement, err = db.Prepare("SELECT * FROM mytable")
    if err != nil {
        mylogger.Panic("Loading SQL Prepared Statement Failed")
    }
}

使用 testify 编写测试时,我只能捕获以下错误:

    PanicsWithError(t, "test", func() {
        LoadPreparedStatements()
    })

Panic value:    &logrus.Entry{Logger:(*logrus.Logger)(0xc0000ba000), Data:logrus.Fields{"context":"MyLogger"}, Time:time.Date(2022, time.November, 1, 21, 49, 27, 889501622, time.Local), Level:0x0, Caller:(*runtime.Frame)(nil), Message:"Loading SQL Prepared Statement Failed", Buffer:(*bytes.Buffer)(nil), Context:context.Context(nil), err:""}

有什么方法可以测试返回的消息吗?

【问题讨论】:

    标签: go testify logrus


    【解决方案1】:

    除了编写自己的测试之外,我找不到任何方法来做到这一点。我使用以下代码实现了一个测试 logrus 响应的断言。如果引发的错误不是来自 logrus,它可能会出现问题,但它允许我编写我想要的断言。

    type tHelper interface {
        Helper()
    }
    
    // didPanic returns true if the function passed to it panics. Otherwise, it returns false.
    func didPanic(f assert.PanicTestFunc) (didPanic bool, message interface{}, stack string) {
        didPanic = true
    
        defer func() {
            message = recover()
            if didPanic {
                stack = string(debug.Stack())
            }
        }()
    
        // call the target function
        f()
        didPanic = false
    
        return
    }
    func PanicsWithLogrusError(t assert.TestingT, errString string, f assert.PanicTestFunc, msgAndArgs ...interface{}) bool {
        if h, ok := t.(tHelper); ok {
            h.Helper()
        }
    
        funcDidPanic, panicValue, panickedStack := didPanic(f)
        if !funcDidPanic {
            return assert.Fail(t, fmt.Sprintf("func %#v should panic
    	Panic value:	%#v", f, panicValue), msgAndArgs...)
        }
        panicErr, ok := panicValue.(*logrus.Entry)
    
        if !ok || panicErr.Message != errString {
            return assert.Fail(t, fmt.Sprintf("func %#v should panic with logrus error message:	%#v
    	Panic value:	%#v
    	Panic stack:	%s", f, errString, panicErr.Message, panickedStack), msgAndArgs...)
        }
    
        return true
    }
    
        PanicsWithLogrusError(t, "Loading SQL Prepared Statement Failed", func() {
            LoadPreparedStatements()
        })
    
    

    以上使测试通过。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-08-01
      • 2010-11-26
      • 1970-01-01
      • 1970-01-01
      • 2018-04-04
      • 2019-06-16
      • 1970-01-01
      相关资源
      最近更新 更多