如何在Go语言中以一行代码断言一行中的多个值

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

How to Assert Multiple values from one single row in one line in Go

问题

如何在一行中断言单行中的多个值

assert.Equal(t, expected_1, actual_1, expected_2, actual_2...)

我的当前代码:

// act
row := tx.QueryRow("select operation, primary_key, before_change, change, changed_at from foo.bar = 'I' order by 1 desc limit 1;")

c := columns{}
row.Scan(&c.operation, &c.primaryKey, &c.beforeChange, &c.change, &c.changedAt)
assert.Equal(t, 0, c.primaryKey)
assert.Equal(t, "I", c.operation)
assert.Equal(t, "", c.beforeChange)
assert.Equal(t, "", c.change)
assert.NotEmpty(t, c.changedAt)

非常感谢任何帮助

请注意,我只翻译了你提供的内容,并返回了翻译后的结果。如果你有其他问题或需要进一步的帮助,请告诉我。

英文:

how to assert multiple values from single row one line

assert.Equal(t, expected_1, actual_1, expected_2, actual_2...)

my current code:

// act
row := tx.QueryRow("select operation, primary_key, before_change, change, changed_at from foo.bar = 'I' order by 1 desc limit 1;")

c := columns{}
row.Scan(&c.operation, &c.primaryKey, &c.beforeChange, &c.change, &c.changedAt)
assert.Equal(t, 0, c.primaryKey)
assert.Equal(t, "I", c.operation)
assert.Equal(t, "", c.beforeChange)
assert.Equal(t, "", c.change)
assert.NotEmpty(t, c.changedAt)

Any help greatly appreciated.

答案1

得分: 0

简短回答: 你不应该这样做。

将测试组合在一起可以使你的代码更容易编写,但可读性较差。更重要的是,它会使测试失败更难以诊断。假设从现在开始的6个月后,其中一个测试开始失败。你如何知道失败是由于c.operation不符合预期,还是c.change

更详细的回答: 考虑使用深度相等比较和文本差异输出。

通过结合使用reflect.DeepEqualgo-spew和一个差异库,你可以轻松地编写一个断言方法,对两个结构体进行深度相等比较,如果它们不匹配,则生成一个文本差异输出,便于诊断失败。

我有一个在我个人项目中使用的库,可以实现这个功能。github.com/flimzy/diff 它并不是真正用于公开使用,我建议只将其用作参考。但你可以使用它作为示例:

row := tx.QueryRow("select operation, primary_key, before_change, change, changed_at from foo.bar = 'I' order by 1 desc limit 1;")

c := columns{}
row.Scan(&c.operation, &c.primaryKey, &c.beforeChange, &c.change, &c.changedAt)
expected := columns{
    operation: "I",
}
if d := diff.Interface(expected, c); d != "" {
    t.Error(d)
}

关于如何处理此类测试中的changedAt列,我将其留给读者作为练习。

英文:

Short answer: You shouldn't do that.

Combining tests like that makes your code easier to write, but less readable. More importantly, it makes a test failure harder to diagnose. Suppose that 6 months from now, one of those tests starts failing. How will you know if the failure is due to c.operation not matching expectations, or c.change?

Longer answer: Consider doing a deep-equal comparison, with a textual diff output.

By combining reflect.DeepEqual, go-spew, and a diff library, you can easily put together an assertion method that does a deep equal comparison of two structs, and if they don't match, produces a textual diff output that will make it easy to diagnose a failure.

I have a library that does this for use in my own personal projects. github.com/flimzy/diff It's not really intended for public consumption--I suggest just using it only for inspiration. But using it as an example:

row := tx.QueryRow("select operation, primary_key, before_change, change, changed_at from foo.bar = 'I' order by 1 desc limit 1;")

c := columns{}
row.Scan(&c.operation, &c.primaryKey, &c.beforeChange, &c.change, &c.changedAt)
expected := columns{
    operation: "I",
}
if d := diff.Interface(expected, c); d != "" {
    t.Error(d)
}

I leave it as an exercise for the reader how to handle the changedAt column in such tests.

huangapple
  • 本文由 发表于 2017年6月16日 03:11:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/44575201.html
匿名

发表评论

匿名网友

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

确定