为了账号安全,请及时绑定邮箱和手机立即绑定

Google App Engine 数据存储区 - 测试查询失败

Google App Engine 数据存储区 - 测试查询失败

Go
慕容森 2021-09-13 19:40:13
我目前正在尝试测试我的一段代码,该代码在放入新实体之前对数据存储运行查询,以确保不会创建重复项。我编写的代码在应用程序的上下文中运行良好,但我为该方法编写的测试失败了。似乎我无法通过测试包上下文中的查询访问放入数据存储区的数据。一种可能性可能在于goapp test读取的输出:Applying all pending transactions and saving the datastore。这行在调用 get 和 put 方法后打印出来(我用日志语句验证了这一点)。我尝试关闭上下文并为不同的操作创建一个新的上下文,但不幸的是,这也无济于事。下面是一个简单的测试用例,它放入一个对象,然后对其运行查询。任何帮助,将不胜感激。type Entity struct {    Value string}func TestEntityQuery(t *testing.T) {    c, err := aetest.NewContext(nil)    if err != nil {        t.Fatal(err)    }    defer c.Close()    key := datastore.NewIncompleteKey(c, "Entity", nil)    key, err = datastore.Put(c, key, &Entity{Value: "test"})    if err != nil {        t.Fatal(err)    }    q := datastore.NewQuery("Entity").Filter("Value =", "test")    var entities []Entity    keys, err := q.GetAll(c, &entities)    if err != nil {        t.Fatal(err)    }    if len(keys) == 0 {        t.Error("No keys found in query")    }    if len(entities) == 0 {        t.Error("No entities found in query")    }}
查看完整描述

3 回答

?
叮当猫咪

TA贡献1776条经验 获得超12个赞

您的测试代码没有任何问题。问题在于数据存储本身。HR 数据存储区中的大多数查询不是“立即一致”而是最终一致。您可以在Datastore文档中阅读有关此内容的更多信息。

所以基本上发生的事情是你将一个实体放入数据存储区,SDK 的数据存储区“模拟”你可以在生产中观察到的延迟,所以如果你在这之后运行查询(这不是祖先查询),查询结果将不包括您刚刚保存的新实体。

如果在datastore.Put()和之间放置几秒钟 sleep q.GetAll(),您将看到测试通过。尝试一下。在我的测试中,只睡 100 毫秒就足够了,而且测试总是通过。但是在为这种情况编写测试时,请使用StronglyConsistentDatastore: trueJonhGB 的答案中所见的选项。

如果您使用Ancestor 查询,您还会看到测试通过而没有睡眠,因为它们是强一致性的


查看完整回答
反对 回复 2021-09-13
?
慕村225694

TA贡献1880条经验 获得超4个赞

为了在最新版本的 aetest 中称赞@JohnGB 的回答,还有更多步骤可以获取具有强一致性的上下文。首先创建一个实例,然后从该实例创建一个请求,您可以使用它来生成上下文。


inst, err := aetest.NewInstance(

&aetest.Options{StronglyConsistentDatastore: true})


if err != nil {

    t.Fatal(err)

}

defer inst.Close()


req, err := inst.NewRequest("GET", "/", nil)

if err != nil {

    t.Fatal(err)

}


ctx := appengine.NewContext(req)


查看完整回答
反对 回复 2021-09-13
  • 3 回答
  • 0 关注
  • 197 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信