AppEngine Objectify Java 单元测试对象缓存错误
AppEngine Objectify Java Unit Test Object Cache Error
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()
调用来清除会话缓存。这并不能避免所有情况下的错误。
这只发生在单元测试环境中,而不是在开发或生产服务器中。
在您发布的代码中,是的,您将获得相同的对象 - 这就是会话缓存的工作方式。保存后清除会话缓存确实会给你一个从数据存储(或内存缓存)加载的新对象。但我的猜测是这不是你真正想要测试的。
我猜测您正试图在测试中模拟多个后端调用。 IRL,每个后端调用都将在其自己的服务器端上下文中运行。所以我推荐的是为每个调用创建一个上下文,使用闭包:
@Test
public void testUserDataQuery throws Exception {
...
req(() -> saveUserData());
...
req(() -> getUserData());
...
}
其中 req()
执行 Objectify 上下文的 begin()/close()(以及您的容器通常执行的任何其他特定于请求的处理)。您可以在 before/after.
中保留 Objectify 初始化
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()
调用来清除会话缓存。这并不能避免所有情况下的错误。
这只发生在单元测试环境中,而不是在开发或生产服务器中。
在您发布的代码中,是的,您将获得相同的对象 - 这就是会话缓存的工作方式。保存后清除会话缓存确实会给你一个从数据存储(或内存缓存)加载的新对象。但我的猜测是这不是你真正想要测试的。
我猜测您正试图在测试中模拟多个后端调用。 IRL,每个后端调用都将在其自己的服务器端上下文中运行。所以我推荐的是为每个调用创建一个上下文,使用闭包:
@Test
public void testUserDataQuery throws Exception {
...
req(() -> saveUserData());
...
req(() -> getUserData());
...
}
其中 req()
执行 Objectify 上下文的 begin()/close()(以及您的容器通常执行的任何其他特定于请求的处理)。您可以在 before/after.