Testing the Google App Engine ThreadManager outside of GAE

I wrote JUnit (4.10) unit test, which makes the following call com.google.appengine.api.ThreadManager:

ThreadManager.currentRequestThreadFactory();

When this test runs, I get NullPointerExceptionfrom this method currentRequestThreadFactory:

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)

When I pull out the source for ThreadManagerand look at line 39 (which is the source of the NPE), I see:

public static ThreadFactory currentRequestThreadFactory() {
        return (ThreadFactory) ApiProxy.getCurrentEnvironment().getAttributes()
            .get(REQUEST_THREAD_FACTORY_ATTR);
}

Thus, it seems to be ApiProxy.getCurrentEnvironment()null, and when it is called getAttribute(), the NPE is thrown. I confirmed this by adding some new print statements above in my unit test code:

if(ApiProxy.getCurrentEnvironment() == null)
    System.out.println("Environment is null.");

, GAE " " , ( ), . : GAE ? , ApiProxy ? , ? , (ThreadManager#currentRequestThreadFactory ApiProxy#getCurrentEnvironment), . .

. , appengine-testing.jar, SDK. JAR ApiProxyLocal.class, , , ApiProxy, JUnit, NPE. ( ), : ThreadManager ?

+5
4

ThreadManager.currentRequestThreadFactory() . ThreadFactory , .

- Guice:

public static class MyService {
  private final ThreadFactory threadFactory;

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

  ...
}

MyService ThreadFactory MyService Executors.defaultThreadFactory().

:

bind(ThreadFactory.class)
    .toInstance(ThreadManager.currentRequestThreadFactory());

, , , ThreadFactory

+1

, LocalServiceTestHelper .

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

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

@AfterClass
public static void finalTearDown() {
    helper.tearDown();
}
+3

ApiProxy.Environment, http://code.google.com/appengine/docs/java/howto/unittesting.html

getAttributes() - , REQUEST_THREAD_FACTORY_ATTR .

, :

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

, unit test, java ApiProxy.

LocalServiceTestCase TestCase, - :

super.setUp();

helper1.setUp();

setEnvironment();

:

public static void setEnvironment() {

    if (ApiProxy.getCurrentEnvironment() == null) {  

        ApiProxyLocal apl = LocalServiceTestHelper.getApiProxyLocal();

        ApiProxy.setEnvironmentForCurrentThread(new TEnvironment());

        ApiProxy.setDelegate(apl);

    }
}

URL- TEnvironment.

, unsetEnvironment().

In your case, unit test, if you started a new java thread, you can simply use the static method at the beginning of your method:

public void run() {

    LocalServiceTestCase.setEnvironment();
0
source

All Articles