我有一个测试遵循以下结构:
var testInstance aetest.Instance // initialized by a TestMain
TestThing(t *testing.T) {
defer cleanupGoogleDatastore(t, testInstance)
// insert basic test fixtures
// insert some new records here
// test assertions, etc.
}
这个
cleanupGoogleDatastore
方法只对特定实体类型的所有实体运行数据存储查询,然后逐个删除它们。资料来源:
func cleanupGoogleDatastore(t *testing.T, testInstance aetest.Instance) {
q := datastore.NewQuery("Order")
ctx := GetContext(t, testInstance)
scanner := q.Run(ctx)
for {
var o model.Order
key, err := scanner.Next(&o)
if err == datastore.Done {
return
}
if err != nil {
t.Fatal(err.Error())
}
err = datastore.Delete(ctx, key)
if err != nil {
t.Fatal(err.Error())
}
}
}
我遇到的问题是,在“基本测试设备”之后插入的记录不会被这个延迟的清除语句删除。
如果我将此测试函数改为如下所示:
var testInstance aetest.Instance // initialized by a TestMain
TestThing(t *testing.T) {
defer cleanupGoogleDatastore(t, testInstance)
// insert basic test fixtures
// insert some new records here
defer cleanupGoogleDatastore(t, testInstance)
// note that I have to call it TWICE - just moving it here is not enough.
// test assertions, etc.
}
然后
新创建的记录在测试结束时也会被删除。我的理解是
deferred
函数只是在原始函数作用域的末尾调用,这意味着查询在测试结束之前不会被构造和运行,但这里似乎不是这样。似乎正在构造查询
当调用defer语句时
然后在测试结束时执行。
我试过搬家
清理谷歌数据存储
关闭(例如。
defer func() { cleanupGoogleDatastore(t, testInstance }()
但这并没有改变什么。
我怀疑这是函数参数在调用defer而不是调用函数时被求值的情况,但是
t
和
testInstance
是指针而不是直接值,我不确定这是怎么发生的。没有其他证据表明这两个值已经改变。在不同的逻辑计算点打印出两个结构的字段不会显示任何新的内容。
怎么回事?