英文:
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.DeepEqual
、go-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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论