duanduan8439 2015-02-18 17:56
浏览 22
已采纳

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

I am currently trying to test a piece of my code that runs a query on the datastore before putting in a new entity to ensure that duplicates are not created. The code I wrote works fine in the context of the app, but the tests I wrote for that methods are failing. It seems that I cannot access data put into the datastore through queries in the context of the testing package.

One possibility might lie in the output from goapp test which reads: Applying all pending transactions and saving the datastore. This line prints out after both the get and put methods are called (I verified this with log statements).

I tried closing the context and creating a new one for the different operations, but unfortunately that didn't help either. Below is a simple test case that Puts in an object and then runs a query on it. Any help would be appreciated.

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条回答 默认 最新

  • dragon4808 2015-02-18 23:10
    关注

    There is nothing wrong with your test code. The issue lies in the Datastore itself. Most queries in the HR Datastore are not "immediately consistent" but eventually consistent. You can read more about this in the Datastore documentation.

    So basically what happens is that you put an entity into the Datastore, and the SDK's Datastore "simulates" the latency that you can observe in production, so if you run a query right after that (which is not an ancestor query), the query result will not include the new entity you just saved.

    If you put a few seconds sleep between the datastore.Put() and q.GetAll(), you will see the test passes. Try it. In my test it was enough to sleep just 100ms, and the test always passed. But when writing tests for such cases, use the StronglyConsistentDatastore: true option as can be seen in JonhGB's answer.

    You would also see the test pass without sleep if you'd use Ancestor queries because they are strongly consistent.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 vue3页面el-table页面数据过多
  • ¥100 vue3中融入gRPC-web
  • ¥15 kali环境运行volatility分析android内存文件,缺profile
  • ¥15 写uniapp时遇到的问题
  • ¥15 vs 2008 安装遇到问题
  • ¥15 matlab有限元法求解梁带有若干弹簧质量系统的固有频率
  • ¥15 找一个网络防御专家,外包的
  • ¥100 能不能让两张不同的图片md5值一样,(有尝)
  • ¥15 informer代码训练自己的数据集,改参数怎么改
  • ¥15 请看一下,学校实验要求,我需要具体代码