2012-07-09 37 views
3

我很難讓Jersey,AppEngine和JUnit工作。當前錯誤如下:AppEngine Jersey Junit測試不起作用(API未註冊此線程)

此線程未註冊API環境。

我做如下:

  • 載入helper.setUp()(LocalDataStoreService)以上的JUnit @Before註釋

  • 過的JUnit @Before創建灰熊Web服務器的實例註釋

  • 執行的testCreateCard測試

  • 停止灰熊Web服務器

  • 了JUnit的@After註釋運行helper.tearDown()方法

我啓動(運行方式)JUnit測試與Eclipse靛藍(包括我在Java的構建路徑的罐子)。

這似乎是澤西或灰熊Webcontainer打開新的線程不能與本地數據存儲區方法helper.setUp()和helper.tearDown()。

我發現了幾個問題/答案,但與澤西島使用AppEngine無關。

有沒有人可以幫忙?實際上可以使用Jersey和AppEngine和JUnit進行設置嗎?我嘗試了幾種可能的休息和球衣測試框架,但所有嘗試都以錯誤和調試結束,並且沒有任何結果發佈到AppEngine Mailinglist。

我最後的希望是我的當前設置有:

  • 灰熊2.1(澤西提供)

  • 新澤西州1.12

  • JUnit的4.10

堆棧跟蹤是如下:

java.lang.NullPointerException: No API environment is registered for this thread. 
    at com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(DatastoreApiHelper.java:86) 
at  com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace(DatastoreApiHelper.java:96) 
at com.google.appengine.api.datastore.Key.<init>(Key.java:106) 
at com.google.appengine.api.datastore.Key.<init>(Key.java:90) 
at com.google.appengine.api.datastore.Key.<init>(Key.java:86) 
at com.google.appengine.api.datastore.Entity.<init>(Entity.java:125) 
at com.google.appengine.api.datastore.Entity.<init>(Entity.java:106) 
at org.datanucleus.store.appengine.DatastoreFieldManager.<init>(DatastoreFieldManager.java:189) 
at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertPreProcess(DatastorePersistenceHandler.java:354) 
at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObjects(DatastorePersistenceHandler.java:267) 
at org.datanucleus.store.appengine.DatastorePersistenceHandler.insertObject(DatastorePersistenceHandler.java:256) 
at org.datanucleus.state.JDOStateManagerImpl.internalMakePersistent(JDOStateManagerImpl.java:3185) 
at org.datanucleus.state.JDOStateManagerImpl.makePersistent(JDOStateManagerImpl.java:3161) 
at org.datanucleus.ObjectManagerImpl.persistObjectInternal(ObjectManagerImpl.java:1298) 
at org.datanucleus.ObjectManagerImpl.persistObject(ObjectManagerImpl.java:1175) 
at org.datanucleus.jdo.JDOPersistenceManager.jdoMakePersistent(JDOPersistenceManager.java:669) 
at org.datanucleus.jdo.JDOPersistenceManager.makePersistent(JDOPersistenceManager.java:694) 
at com.acolsolutions.loyaltycard.dataobjects.CardDAO.create(CardDAO.java:23) 
at com.acolsolutions.loyaltycard.resources.CardResource.create(CardResource.java:32) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60) 
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$ResponseOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:205) 
at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75) 
at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288) 
at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108) 
at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147) 
at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84) 
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1483) 
at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1414) 
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1363) 
at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1353) 
at com.sun.jersey.server.impl.container.grizzly2.GrizzlyContainer._service(GrizzlyContainer.java:215) 
at com.sun.jersey.server.impl.container.grizzly2.GrizzlyContainer.service(GrizzlyContainer.java:185) 
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:163) 
at org.glassfish.grizzly.http.server.HttpHandlerChain.service(HttpHandlerChain.java:207) 
at org.glassfish.grizzly.http.server.HttpHandler.doHandle(HttpHandler.java:163) 
at org.glassfish.grizzly.http.server.HttpServerFilter.handleRead(HttpServerFilter.java:164) 
at org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:265) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:200) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:134) 
at org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:112) 
at org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:78) 
at org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:816) 
at org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:111) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55) 
at org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135) 
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:566) 
at org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:546) 
at java.lang.Thread.run(Unknown Source) 

我的球衣測試類看起來如下:

import java.io.IOException; 
import java.net.URI; 
import java.util.HashMap; 
import java.util.Map; 

import javax.ws.rs.core.UriBuilder; 

import org.junit.After; 
import org.junit.Before; 
import org.junit.Test; 

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

import org.glassfish.grizzly.http.server.HttpServer; 

import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory; 
import com.sun.jersey.api.core.PackagesResourceConfig; 
import com.sun.jersey.api.core.ResourceConfig; 
import com.sun.jersey.api.client.WebResource; 
import com.sun.jersey.api.client.Client; 

import org.codehaus.jettison.json.JSONObject; 

public class CardResourceTests { 
private final LocalServiceTestHelper helper = new LocalServiceTestHelper(
     new LocalDatastoreServiceTestConfig()); 

private HttpServer httpServer; 
private URI uri; 

@Before 
public void setUp() throws Exception { 
    helper.setUp(); 

    uri = UriBuilder.fromUri("http://localhost/").port(9998).build(); 
    ResourceConfig rc = new PackagesResourceConfig("com.acolsolutions.loyaltycard.resources"); 
    httpServer = GrizzlyServerFactory.createHttpServer(uri, rc); 
} 

@After 
public void tearDown() throws Exception { 
    helper.tearDown(); 

    httpServer.stop(); 
} 

@Test 
public void testCreate() { 
    boolean thrown = false; 
    Client client = Client.create(); 
    WebResource webResource = client.resource(uri); 
    JSONObject card = new JSONObject(); 

    try { 
     card.put("id", "1") 
     .put("name", "Name of Card") 
     .put("code", "123456") 
     .put("codeTypeId", "1") 
     .put("cardProviderName", "The Card Provider") 
     .put("picturePath", "provider.jpg") 
     .put("cardProviderUrl", "http://www.provider.com") 
     .put("creationDate", "Sun Jun 10 08:55:14 UTC 2012") 
     .put("modificationDate","Sun Jun 10 08:55:14 UTC 2012"); 
    webResource.path("cards").type("application/json").post(card); 
    } catch(Exception e) { 
     e.printStackTrace(); 
     thrown = true;   
    } 

    assertEquals("Result", false, thrown); 
} 
} 

回答

3

你爲什麼想如果你使用的AppEngine灰熊用? Appengine是你的容器,而不是灰熊..

+0

謝謝你帶我到這條路上瑞克。是的,使用AppEngine作爲容器會很好。但是,我怎樣才能通過JUnit之前和之後的註釋啓動整個Web框架?當我運行JUnit時,我希望我的環境開始測試,然後再關閉。 Google文檔只提到通過命令行啓動它。我剛纔讀到Jetty會產生新的進程。我怎樣才能限制Web服務器只產生一個進程? – 2012-07-10 19:36:35

+1

您不會爲單元測試啓動Web容器。這是appengine測試工具的用途。您應該以編程方式測試球衣服務,而不是通過發送請求。換句話說,不要使用球衣客戶端類來發送請求,而是直接在服務類上調用方法。如果你啓動一個容器,那不是一個單元測試......這是一個集成測試。 – 2012-07-10 20:06:06

+0

好吧,我明白了。我會盡力做到這一點,謝謝。但即使如此,那裏似乎也有許多人使用JUnit進行集成測試。所以我猜他們在這種情況下「濫用」JUnit?那麼我將如何進行集成測試?只需通過編寫客戶端並在啓動後連接到服務器? – 2012-07-11 19:09:40