[英]Right way to assert that slice of pointers to strings contains expected strings?
Is there an easy and compact way using Testify to assert that a slice of pointers to strings contains a pointer to a string that matches my expectation?是否有一种简单而紧凑的方法使用 Testify 来断言一段指向字符串的指针包含指向符合我期望的字符串的指针?
Imagine that you're getting a slice of pointers to strings back from a function call (maybe from an API), and you'd like to validate that it contains pointers to the strings that you'd expect.想象一下,您正在从 function 调用(可能来自 API)中获取一部分指向字符串的指针,并且您想要验证它是否包含指向您期望的字符串的指针。 To simulate that, I'll just make a test data structure to illustrate my point:
为了模拟这一点,我将制作一个测试数据结构来说明我的观点:
// Shared Fixture
var one = "one"
var two = "two"
var three = "three"
var slice = []*string{&one, &two, &three}
Now I want to write a test that asserts the slice contains an expected value.现在我想编写一个断言切片包含预期值的测试。 I could write this test:
我可以写这个测试:
func TestSliceContainsString(t *testing.T) {
assert.Contains(t, slice, "one")
}
It doesn't work: []*string{(*string)(0x22994f0), (*string)(0x2299510), (*string)(0x2299500)} does not contain "one"
.它不起作用:
[]*string{(*string)(0x22994f0), (*string)(0x2299510), (*string)(0x2299500)} does not contain "one"
。 Makes sense, the slice contains pointers to strings, and the string "one" is not one of those pointers.有道理,切片包含指向字符串的指针,而字符串“one”不是这些指针之一。
I could convert it first.我可以先转换它。 It takes more code, but it works:
它需要更多代码,但它有效:
func TestDereferencedSliceContainsString(t *testing.T) {
deref := make([]string, len(slice))
for i, v := range slice {
deref[i] = *v
}
assert.Contains(t, deref, "one")
}
I can also pass a pointer to a string as my expectation:我也可以按照我的期望传递一个指向字符串的指针:
func TestSliceContainsPointerToExpectation(t *testing.T) {
expect := "one"
assert.Same(t, &one, &one)
assert.NotSame(t, &one, &expect)
// How can I assert that they contain values
assert.Contains(t, slice, &expect)
}
Honestly, that's not bad.老实说,这还不错。 I can assert that a reference to a string (pointing to a difference memory location) contains the value that I expect.
我可以断言对字符串的引用(指向差异 memory 位置)包含我期望的值。 The main annoyance with this path is that I can't pass a reference to a literal, which would make it take less space:
这条路径的主要烦恼是我无法传递对文字的引用,这会占用更少的空间:
func TestSliceContainsString(t *testing.T) {
assert.Contains(t, slice, &"one")
}
Is there another approach that I'm not considering?还有其他我没有考虑的方法吗? Is one of these more idiomatic of golang/testify?
golang / testify 中的其中一个更惯用吗?
Yes, unfortunately the &"one"
syntax isn't valid (a few years ago, I opened an issue to allow that syntax; it was closed, though Rob Pike opened a similar issue more recently).是的,不幸的是
&"one"
语法无效(几年前,我打开了一个允许该语法的问题;它被关闭了,尽管 Rob Pike 最近打开了一个类似的问题)。
For now, I think the best approach is to just take the address of a variable, as in your TestSliceContainsPointerToExpectation
.目前,我认为最好的方法是只获取变量的地址,就像在
TestSliceContainsPointerToExpectation
中一样。 Or, if you're doing this often, you can write a simple stringPtr
function so you can do it as a one-liner:或者,如果你经常这样做,你可以写一个简单的
stringPtr
function 这样你就可以把它作为一个单行代码来完成:
func stringPtr(value string) *string {
return &value
}
func TestSliceContainsString(t *testing.T) {
assert.Contains(t, slice, stringPtr("one"))
}
Or, if you're using at least Go 1.18 (with generics), you can make a generic ptr
function:或者,如果您至少使用 Go 1.18(使用泛型),则可以制作一个通用
ptr
function:
func ptr[T any](value T) *T {
return &value
}
func TestSliceContains(t *testing.T) {
assert.Contains(t, slice, ptr("one"))
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.