3

我正在为严重依赖 Google App Engine 服务(如 Memcache 和 Datastore)的 Google App Engine Java 应用程序编写测试(集成和单元)。为了使用这些服务在本地测试我的应用程序,我在所有测试用例的父类中都有这一行:

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

我用这个函数调用开始每个测试(通过TestNG的@BeforeMethod注释):

helper.setUp();

我用这个函数调用结束每个测试(通过TestNG的@AfterMethod注释):

helper.tearDown();

(这里参考了TestNG annotations and local unit testing for Google App Engine's Java Runtime,以备不时之需。尤其是后面的链接,请注意我的代码严格遵循Google给出的示例)

需要注意的一点是,我在 Java 应用程序中的一个 servlet 使用了 MemcacheService 实例。它被 Guice 注入到 servlet 的构造函数中。

现在,我构建我的代码并通过调用来运行它mvn clean install,这将启动一个Jetty实例并在代码编译后运行我的测试。令我懊恼的是,我在 TestNG 报告大规模测试失败之前打印了这个堆栈跟踪:

SEVERE: Received exception tearing down config of type com.google.appengine.tools.development.testing.LocalMemcacheServiceTestConfig
java.lang.NullPointerException
at com.google.appengine.tools.development.testing.LocalServiceTestHelper.getLocalService(LocalServiceTestHelper.java:495)
at com.google.appengine.tools.development.testing.LocalMemcacheServiceTestConfig.getLocalMemcacheService(LocalMemcacheServiceTestConfig.java:71)
at com.google.appengine.tools.development.testing.LocalMemcacheServiceTestConfig.tearDown(LocalMemcacheServiceTestConfig.java:47)
at com.google.appengine.tools.development.testing.LocalServiceTestHelper.tearDown(LocalServiceTestHelper.java:438)
at com.ea.pogosocial.AbstractTest.tearDown(AbstractTest.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:80)
at org.testng.internal.Invoker.invokeConfigurationMethod(Invoker.java:564)
at org.testng.internal.Invoker.invokeConfigurations(Invoker.java:213)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:796)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:907)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:1237)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:127)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:111)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:679)

我已经尝试了几乎所有我能想到的来解决这个问题,但我仍然遇到了这个 tearDown() 问题,这真的让我很困惑。除了 put() 和 get(),我没有对 servlet 中的 memcache 实例做任何花哨的事情。有人对我应该做什么有任何想法吗?

如果需要更多信息或代码,我很乐意提供。需要注意的一件事:当我启动我的 Jetty 服务器mvn gae:run并通过 Eclipse 执行 TestNG 测试时,我没有遇到这个问题。也许这是因为我的 servlet 被注入了一个非本地的 memcache 单元测试助手实例,而是一个实际版本的 memcache 服务。

4

3 回答 3

2

我有这个完全相同的错误。对我来说,问题是 Google App Engine SDK 依赖项的版本号不匹配

我有:

  • appengine-api-1.0-sdk:1.8.1.1
  • 应用引擎 API 实验室:1.8.1.1
  • appengine-api-stubs:1.8.1.1
  • 应用引擎测试:1.8.1.1
  • 应用引擎工具 SDK:1.7.2

一旦我将 appengine-tools-sdk 更新为与其余依赖项相同的版本,我的测试又开始通过了。

于 2013-07-05T16:57:05.357 回答
0

我认为您在使用 @BeforeMethod 和 @AfterMethod 注释时遇到了一些小问题。基本上这些注释在每个测试方法执行之前和每个测试方法执行之后调用。如上所述,您不能为单个测试方法分配 @BeforeMethod 和 @AfterMethod 注释。

并尝试在 @BeforeClass 或 @BeforeSuite 注释中实现您的服务器启动。因此,您可以确保在执行测试时服务器已启动。

于 2012-10-10T11:36:41.540 回答
0

只需将这 3 个库(测试库的一部分)添加到您的类路径中:

${SDK_ROOT}/lib/impl/appengine-api.jar
${SDK_ROOT}/lib/impl/appengine-api-labs.jar
${SDK_ROOT}/lib/impl/appengine-api-stubs.jar

这应该可以解决问题。

于 2012-12-14T16:39:16.003 回答