4

在我的应用程序中,我有一组 DAO,我将它们注入我的应用程序层。对于我正在编写的验收测试,我想用数据预加载 dev_server 数据存储,所以我在我的 JUnit 测试中使用相同的 Spring 配置(使用 @ContextConfiguration 注释)将相关 DAO 的实例注入到我的测试中。当我实际去存储一些数据时,例如:

dao.add(entity)

我得到了可怕的“没有为此线程注册 API 环境”。

Caused by: java.lang.NullPointerException: No API environment is registered for this thread.
 at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(DatastoreApiHelper.java:108)
 at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace(DatastoreApiHelper.java:118)
    ....

这可能是因为我的测试用例没有在 GAE application-web.xml 中读取应用程序详细信息(尽管我在这里猜测我可能真的错了);因此它不知道写入 dev_server 上运行的应用程序正在读取/写入的同一数据存储。

如何让我的测试“指向”与应用程序相同的数据存储?是否有一些“数据源”机制可以同时注入到应用程序和测试中?有没有办法让我的测试强制数据存储 api 读取所需的配置?

4

3 回答 3

3

是一个讨论如何进行连接到开发数据存储的单元测试的页面。这是你要找的东西吗?基本上它讨论了两个类,LocalServiceTestHelper 和 LocalDatastoreServiceTestConfig,您可以使用它们来设置测试环境。虽然给出的示例是针对单元测试的,但我相信它也适用于您的情况。

然后,您可以配置开发数据存储是写入磁盘还是仅保存在内存中(用于更快的测试)。如果您希望这些数据与您的开发服务器放在同一个地方,您可能需要调整它,因为我认为默认值是“内存中”选项。如果您查看javadoc,则有一个“setBackingStoreLocation”方法,您可以在其中指向您想要的任何文件。

于 2011-01-22T23:11:43.707 回答
0

我找到了一种解决方法,尽管它不是很好,因为每种测试方法都不会清理数据存储区,如Java 的本地单元测试一文中所述中所解释的那样,但是,每次运行测试类时数据存储区都会开始清理,所以只要你小心一点,情况还不错。

问题是,使用 时,在运行注释SpringJUnit4ClassRunner之前创建了 spring 环境,解决方案是使用并使用静态变量 for ,以便在设置 Spring 环境之前创建它们。@Before@BeforeClassLocalServiceTestHelper

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:META-INF/spring/context-test.xml")
@Transactional
public class MyTest {


    @Inject
    private MyService myService;

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

    @BeforeClass
    public static void beforeClass() {
        helper.setUp();
    }

    @AfterClass
    public static void afterClass() {
        helper.tearDown();
    }

如果有人有更好的解决方案,我会很高兴听到!

于 2013-08-26T22:03:26.210 回答
0

我找到了解决办法!!!!

由于某种原因,测试数据存储区的 Namespace、AppID 和 AuthDomain 字段必须与 dev_server 的字段匹配,然后 dev_server 才能看到测试插入的实体。

您可以使用以下语句查看环境(dev_server 或测试代码)的值

System.out.println(NamespaceManager.get());
System.out.println(ApiProxy.getCurrentEnvironment().getAppId());
System.out.println(ApiProxy.getCurrentEnvironment().getAuthDomain());

在您的 LocalServiceTestHelper 实例(例如:gaeHelper)中,您可以设置测试环境的值

// the NamespaceManager is thread local.
NamespaceManager.set(NamespaceManager.getGoogleAppsNamespace());
gaeHelper.setEnvAppId(<the name of your app in appengine-web.xml>);
gaeHelper.setEnvAuthDomain("gmail.com");

然后 dev_server 将看到您的实体。但是由于同步问题,如果测试在 dev_server 启动后写入数据存储区,则 dev_server 不会看到它,除非它可以强制重新读取文件(我还没有弄清楚)。否则必须重新启动服务器。

于 2011-02-02T11:34:12.040 回答