【问题标题】:AppEngine Objectify Java Unit Test Object Cache ErrorAppEngine Objectify Java 单元测试对象缓存错误
【发布时间】:2018-05-27 20:17:44
【问题描述】:

AppEngine Objectify Java 单元测试给出了一个奇怪的会话缓存错误,如下所述。

测试用例:

private final LocalServiceTestHelper helper = new LocalServiceTestHelper(
        new LocalDatastoreServiceTestConfig());

protected Closeable session;

@Before
public void setUp() throws Exception {        
    helper.setUp();

    ObjectifyService.setFactory(new ObjectifyFactory());
    ObjectifyService.register(UserData.class);
    session = ObjectifyService.begin();
}

@After
public void tearDown() throws Exception {
    session.close();
    helper.tearDown();
}

@Test
public void testUserDataQuery throws Exception {
    ...
    saveUserData();
    ...
    getUserData();
    ...
}

调用 1:

UserData saveUserData {

    ...
    UserData userData = (UserData) ofy().load().key(key).now();
    ...

    // UserData is modified, the modifications are not stored in datastore,
    // as those are temporary.

    return userData;
}

呼叫 2:

UserData getUserData {

    ...
    UserData userData = (UserData) ofy().load().key(key).now();
    ...

    // Return the datastore saved UserData object.
    return userData;
}

执行单元测试用例时,saveUserData 调用中所做的修改在getUserData 查询中可见。即使 ofy().load() 已被调用,UserData 也不会从数据存储中加载,而是从缓存条目中提供。

我已尝试调用ofy().clear() 来清除会话缓存。这并不是在所有情况下都避免错误。

这仅发生在单元测试环境中,而不是在开发或生产服务器中。

【问题讨论】:

    标签: google-app-engine junit4 objectify


    【解决方案1】:

    在您发布的代码中,是的,您将获得相同的对象 - 这就是会话缓存的工作方式。保存后清除会话缓存确实会给您一个从数据存储(或内存缓存)加载的新对象。但我的猜测是,这不是你真正想要测试的。

    我猜测您正在尝试在测试中模拟多个后端调用。 IRL,每个后端调用都将在其自己的服务器端上下文中运行。所以我建议使用闭包为每个调用创建一个上下文:

    @Test
    public void testUserDataQuery throws Exception {
        ...
        req(() -> saveUserData());
        ...
        req(() -> getUserData());
        ...
    }
    

    req() 在哪里执行 Objectify 上下文的 begin()/close()(以及您的容器通常执行的任何其他特定于请求的处理)。您可以在之前/之后保留 Objectify 初始化。

    【讨论】:

    • 是的!我正在做顺序呼叫验证。 saveUserData创建和保存的内容需要在getUserData中。基本上ofy().load() 必须从数据存储而不是缓存加载。有没有办法做到这一点?
    • 我尝试了您在 API 调用之间创建和删除对象化上下文的建议。这仍然没有帮助。我试过MemcacheService.clearAll() 也没有任何帮助。
    • 在调用之间建立一个新的 ofy 上下文是正确的想法。从提供的信息中,我无​​法判断您做错了什么。对不起。
    • 我在保存和获取用户调用之间做错了,因为这个获取用户显示了一些错误。您的解决方案有效,感谢您的建议。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-15
    • 1970-01-01
    • 2021-11-17
    • 2015-04-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多