2 回答
TA贡献1804条经验 获得超3个赞
正如您在 eduncan911 的回答中所见,一种解决方案是嵌入。如果您想将其他字段添加到新结构中,那就太好了。
但是,这不是必需的。创建一个新类型testing.T作为其底层类型(就像你所做的那样)就足够了:
type myT testing.T
func (t *myT) assert(val int) {
if val == 0 {
t.Errorf("%d is zero", val)
}
}
使用它
在TestSomething()我们不能只是调用t.assert(0)因为assert()不是方法testing.T而是我们的myT类型。所以我们需要一个myT可以调用的类型值myT.assert()。
我们不能使用类型断言将 a 转换testing.T为我们的myT类型,因为类型断言要求表达式为接口类型!并且t不是接口类型,而是具体类型:*testing.T.
解决方案非常简单,我们可以使用简单的类型转换,因为myT和testing.T具有相同的底层类型:
my := myT(*t) // Conversion valid, but not yet enough, read on...
以上工作,我们可以调用:
my.assert(0)
但是在运行测试时,它不会失败!这是为什么?这是因为上面的*t解引用、转换和赋值会产生一个副本,并且my是类型myT但是会是的副本*t,所以当我们调用时myT.assert(),它得到一个指针,但是一个指向副本的指针。当myT.assert()调用 时t.Errorf(),它会在副本上注册错误,所以测试框架不会看到这个Errorf()调用。
“最终”解决方案很简单:使用类型转换,但不转换*t,而是转换t本身(它是一个指针)。当然*t不能转换为myT,只能转换为*myT。并且这种类型需要用括号括起来(以避免歧义):
func TestSomething(t *testing.T) {
my := (*myT)(t)
my.assert(0)
}
现在我们很高兴,一切都按预期进行。
注意:myT.assert()如果不想调用多个方法,也可以在一行中调用myT:
func TestSomething(t *testing.T) {
(*myT)(t).assert(0)
}
TA贡献1895条经验 获得超3个赞
您可以使用嵌入来添加所有者方法:
package test
import "testing"
type testingT struct {
*testing.T
}
func (t *testingT) assert(val int) {
if val == 0 {
t.Errorf("%d is zero", val)
}
}
func TestSomething(t *testing.T) {
t2 := &testingT{t}
t2.assert(0)
}
- 2 回答
- 0 关注
- 195 浏览
添加回答
举报