首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在GAE之外测试Google

在GAE之外测试Google
EN

Stack Overflow用户
提问于 2013-02-04 14:19:42
回答 4查看 1.4K关注 0票数 5

我编写了一个JUnit (4.10)单元测试,它对com.google.appengine.api.ThreadManager进行以下调用

代码语言:javascript
复制
ThreadManager.currentRequestThreadFactory();

当此测试运行时,将从此NullPointerException方法中抛出一个currentRequestThreadFactory

代码语言:javascript
复制
Caused by: java.lang.NullPointerException
    at com.google.appengine.api.ThreadManager.currentRequestThreadFactory(ThreadManager.java:39)
    at com.myapp.server.plumbing.di.BaseModule.providesThreadFactory(BaseModule.java:50)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

当我提取ThreadManager的源代码,并查看第39行(它是NPE的来源)时,我看到:

代码语言:javascript
复制
public static ThreadFactory currentRequestThreadFactory() {
        return (ThreadFactory) ApiProxy.getCurrentEnvironment().getAttributes()
            .get(REQUEST_THREAD_FACTORY_ATTR);
}

因此,ApiProxy.getCurrentEnvironment()似乎是空的,当调用它的getAttribute()方法时,会抛出NPE。我在我的单元测试代码中添加了一些新的print语句,从而证实了这一点:

代码语言:javascript
复制
if(ApiProxy.getCurrentEnvironment() == null)
    System.out.println("Environment is null.");

我隐约意识到GAE为其所有服务提供了“测试版本”,但还没有找到(特别是)如何使用它们和设置它们。所以我问: GAE提供这样的测试版本吗?如果是这样,我如何在这里添加一个ApiProxy测试版本?如果没有,我有什么选择?我认为我不能嘲笑这两种方法(ThreadManager#currentRequestThreadFactoryApiProxy#getCurrentEnvironment),因为它们都是静态的。提前谢谢。

编辑:我看到有一个随SDK一起发布的appengine-testing.jar。在这个JAR中有一个ApiProxyLocal.class,我相信它是ApiProxy的一个版本,可以在JUnit测试期间使用,这样可以在不抛出NPE的情况下工作。如果是这种情况(我甚至不确定),那么问题是:如何将它插入到我的ThreadManager中以进行这个测试?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-02-05 04:43:52

我建议避免直接从代码中调用ThreadManager.currentRequestThreadFactory()。相反,将ThreadFactory注入需要创建线程的类中。

一个简单的方法是用Guice:

代码语言:javascript
复制
public static class MyService {
  private final ThreadFactory threadFactory;

  @Inject
  MyService(ThreadFactory threadFactory) {
    this.threadFactory = threadFactory;
  }

  ...
}

在对MyService的测试中,可以将假ThreadFactory传递给MyService构造函数或注入Executors.defaultThreadFactory()

在生产代码中,您将创建一个绑定:

代码语言:javascript
复制
bind(ThreadFactory.class)
    .toInstance(ThreadManager.currentRequestThreadFactory());

当然,如果您还没有准备好跳转到依赖项注入,您可以创建自己的访问器来获取和设置ThreadFactory

票数 1
EN

Stack Overflow用户

发布于 2014-02-18 20:04:41

如果您设置了您的LocalServiceTestHelper,您将从存根中获得正确的线程,如下所示。

代码语言:javascript
复制
private static final LocalServiceTestHelper helper = new LocalServiceTestHelper( new    LocalDatastoreServiceTestConfig());

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

@AfterClass
public static void finalTearDown() {
    helper.tearDown();
}
票数 3
EN

Stack Overflow用户

发布于 2013-08-13 23:06:40

如果您正在按照ApiProxy.Environment中的建议实现http://code.google.com/appengine/docs/java/howto/unittesting.html

然后,getAttributes()方法就是在映射中找不到REQUEST_THREAD_FACTORY_ATTR条目的地方。

你可以补充一下:

代码语言:javascript
复制
attributes.put(REQUEST_THREAD_FACTORY_ATTR, new RequestThreadFactory());

有关其他有用的补充,请参见:http://googleappengine.googlecode.com/svn-history/trunk/java/src/main/com/google/appengine/tools/development/LocalEnvironment.java

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14688645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档