gpt4 book ai didi

java - GAE (Java) 高复制数据存储测试 - 测试用例之间未清除数据存储

转载 作者:搜寻专家 更新时间:2023-11-01 03:53:07 26 4
gpt4 key购买 nike

总结

在使用 Appengine 的 High Replication Datastore 设置单元测试时,我发现了一些奇怪的行为。

我在下面放了一个完整的例子。问题是来自一个测试用例的持久对象可用于后面的测试用例,但只有当后面的测试用例在事务中检索它时才可用。据我了解,tearDown 方法应该完全清除数据存储。

我假设我的设置有问题,或者我遗漏了一些重要的东西。请帮忙。

具体问题

给定下面的代码,为什么输出如下? (特别是我加粗的最后一行)

17-Sep-2013 20:41:35 org.datanucleus.PersistenceConfiguration setProperty

INFO: Property datanucleus.appengine.singletonPMFForName unknown - will be ignored

17-Sep-2013 20:41:36 com.google.appengine.datanucleus.MetaDataValidator validate

INFO: Performing appengine-specific metadata validation for com.test.Thing

17-Sep-2013 20:41:36 com.google.appengine.datanucleus.MetaDataValidator validate

INFO: Finished performing appengine-specific metadata validation for com.test.Thing

17-Sep-2013 20:41:36 com.google.appengine.api.datastore.dev.LocalDatastoreService init

INFO: Local Datastore initialized: Type: Master/Slave Storage: In-memory 17-Sep-2013 20:41:36 com.google.appengine.api.datastore.dev.LocalDatastoreService init

INFO: Local Datastore initialized: Type: Master/Slave Storage: In-memory

[OUTSIDE TRANSACTION] This correctly gets executed.

[INSIDE TRANSACTION] This should not be executed. THING:item

我的评论

除非我在做一些非常愚蠢的事情(这并非不可能),否则在第一个测试用例中保留的项目似乎仍然可用于第二个测试用例中的事务。

第二个测试用例尝试在事务之外获取 getObjectById,并正确抛出异常。

然后它会在事务中尝试相同的操作并检索一个对象,我认为该对象只能是早期测试用例中持久存在的对象。

这是为什么?我做错了什么?非常感谢。

复制问题的代码

我在 Eclipse 中创建了一个新的 Web 应用程序项目,并向其中添加了此屏幕截图中显示的类和 jar:

screenshot of package explorer

类 PMF 看起来像这样:

package com.test;

import javax.jdo.JDOHelper;
import javax.jdo.PersistenceManagerFactory;

public final class PMF {

private static final PersistenceManagerFactory pmfInstance =
JDOHelper.getPersistenceManagerFactory("transactions-optional");

private PMF() {}

public static PMF getInstance() {
if (null == _instance) {
_instance = new PMF();
}
return _instance;
}

public static PersistenceManagerFactory get() {
return pmfInstance;
}

private static PMF _instance;
}

Class Thing 看起来像这样:

package com.test;

import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@PersistenceCapable
public class Thing {

public Thing(String item) {
this.item = item;
this.key = makeKey(item);
}


public static Key makeKey(String item) {
return KeyFactory.createKey("Thing", item);
}

public String getId() {
if (null == key) {
return null;
}
return KeyFactory.keyToString(key);
}

public String getItem() {
return item;
}

public String toString() {
return "THING:" + item;
}

@PrimaryKey
@Persistent
private Key key;
@Persistent
private String item;
}

最后,TestDatastore 类如下所示:

package com.test;

import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;

import junit.framework.TestCase;

import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

public class TestDatastore extends TestCase {

@Override
public void setUp() {
helper.setUp();
}

@Override
public void tearDown() {
helper.tearDown();
}

public void testCreateThing() {

String item = "item";
Thing thing = new Thing(item);

PersistenceManager pm = PMF.get().getPersistenceManager();
Thing persisted = pm.makePersistent(thing);
Thing result = pm.getObjectById(Thing.class, persisted.getId());

assertEquals(item, result.getItem());
}

public void testThingDoesntExist() {

String item = "item";
Thing thing = new Thing(item);

PersistenceManager pm = PMF.get().getPersistenceManager();
Transaction tx = pm.currentTransaction();
try {
Thing testThing = pm.getObjectById(Thing.class, Thing.makeKey(thing.getItem()));
} catch (Exception e) {
System.out.println("[OUTSIDE TRANSACTION] This correctly gets executed.");
}

try {
tx.begin();
Thing testThing = pm.getObjectById(Thing.class, Thing.makeKey(thing.getItem()));
System.out.println("[INSIDE TRANSACTION] This should not be executed. " + testThing);
tx.commit();
} catch (Exception e) {
System.out.println("This doesn't get executed, but it should");
}
}

private final LocalServiceTestHelper helper =
new LocalServiceTestHelper(
new LocalDatastoreServiceTestConfig()
.setDefaultHighRepJobPolicyUnappliedJobPercentage(100));
}

最佳答案

这看起来确实很奇怪。但是,有两件事引起了我的注意:

  1. 您使用 setDefaultHighRepJobPolicyUnappliedJobPercentage(100)。那是故意的吗?也许将其设置为 0?不过可能不是。

  2. 在 Google JDO 示例中,它们似乎总是关闭 pm。尝试这样做(尤其是在 testCreateThing() 中):

    最后{ pm.close();

关于java - GAE (Java) 高复制数据存储测试 - 测试用例之间未清除数据存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18860169/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com