AppEngine Objectify Java单元测试对象缓存错误

时间:2018-05-27 20:17:44

标签: google-app-engine junit4 objectify

AppEngine Objectify Java Unit Test会产生一个奇怪的会话缓存错误,如下所述。

测试用例:

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,而是从缓存的条目中提供。{/ p>

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

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

1 个答案:

答案 0 :(得分:1)

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

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

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

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