2013-02-04 16 views
5

की मैं एक JUnit (4.10) इकाई परीक्षण com.google.appengine.api.ThreadManager के लिए निम्न कॉल करता है कि लिखा है बाहर:परीक्षण Google अनुप्रयोग इंजन ThreadManager GAE

ThreadManager.currentRequestThreadFactory(); 

जब इस परीक्षण रन, मैं एक NullPointerException पाने के भीतर से फेंके जाने इस 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) 

जब मैं ThreadManager के लिए स्रोत नीचे लाएँ, और लाइन 39 (जो एनपीई का स्रोत है) को देखो, मैं देख रहा हूँ:

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

तो ऐसा लगता है कि ApiProxy.getCurrentEnvironment() शून्य है, और जब यह getAttribute() विधि कहा जाता है, तो एनपीई फेंक दिया जाता है। मैं अपने इकाई परीक्षण कोड में कुछ नए प्रिंट बयान उच्च को जोड़कर इस की पुष्टि की है:

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

मैं थोड़ा पता है कि GAE अपनी सभी सेवाओं के लिए "परीक्षण संस्करण" प्रदान करता है, लेकिन करने के लिए नहीं कर पाए हैं ढूंढें (विशेष रूप से) उन्हें कैसे उपयोग करें और उन्हें सेट अप करें। तो मैं पूछता हूं: क्या जीएई ऐसे परीक्षण संस्करण पेश करता है? यदि हां, तो मैं यहां ApiProxy परीक्षण संस्करण कैसे जोड़ूं? और यदि नहीं, तो मेरे विकल्प क्या हैं? मुझे नहीं लगता कि मैं या तो विधि (ThreadManager#currentRequestThreadFactory या ApiProxy#getCurrentEnvironment) का नकल कर सकता हूं क्योंकि वे दोनों स्थिर हैं। अग्रिम में धन्यवाद।

संपादित करें: मुझे लगता है कि appengine-testing.jar है जो एसडीके के साथ जहाज है। इस जेएआर के अंदर एक ApiProxyLocal.class है कि मैं मानता हूंApiProxy का एक संस्करण है जिसका उपयोग जुनीट परीक्षण के दौरान किया जा सकता है, जो एनपीई फेंकने के बिना काम करेगा। अगर ऐसा है (जो मुझे भी यकीन नहीं है), तो सवाल यह है कि: मैं इस परीक्षण के लिए अपने ThreadManager में इसे कैसे इंजेक्ट कर सकता हूं?

+0

आप पढ़ सकते हैं https://developers.google.com/appengine/docs/java/tools/localunittesting#Introducing_the_Java_Testing_Utilities है? – NamshubWriter

+0

फिर से धन्यवाद - ये परीक्षण JARs (उस आलेख में संदर्भित) मुझे स्थानीय ** servce ** कक्षाओं और विधियों तक पहुंच प्रदान करते हैं, लेकिन 'थ्रेडमेनगर' का परीक्षण संस्करण नहीं ... – IAmYourFaja

उत्तर

1

मैं सीधे आपके कोड से ThreadManager.currentRequestThreadFactory() पर कॉल करने से बचने का सुझाव देता हूं। इसके बजाय, ThreadFactory उस वर्ग में इंजेक्ट करें जिसे थ्रेड बनाने की आवश्यकता है।

एक आसान तरीका यह करने के लिए Guice के साथ है:

public static class MyService { 
    private final ThreadFactory threadFactory; 

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

    ... 
} 
MyService के लिए

अपने परीक्षणों में, आप या तो MyService निर्माता के लिए एक नकली ThreadFactory पास या Executors.defaultThreadFactory() इंजेक्षन सकता है।

अपने उत्पादन कोड में, आप बना सकते हैं एक बाध्यकारी:

bind(ThreadFactory.class) 
    .toInstance(ThreadManager.currentRequestThreadFactory()); 
बेशक

, यदि आप निर्भरता इंजेक्शन में कूदने के लिए, आप अपने खुद accessors हो और ThreadFactory

स्थापित करने के लिए बना सकते हैं तैयार नहीं हैं
+0

धन्यवाद @NamshubWriter, लेकिन मैं नहीं पूछ रहा हूँ * 'थ्रेडमेनगर' * इंजेक्ट कैसे करें। मैं कह रहा हूं कि ** मैं एक jUnit परीक्षण के अंदर से 'com.google.appengine.api.ThreadManager.currentRequestThreadFactory' निष्पादित नहीं कर सकता। ** ऐसा इसलिए है क्योंकि एक आंतरिक, निर्विवाद रूप से स्थैतिक' ApiProxy.getCurrentEnvironment() 'विधि है वह एक एनपीई फेंक रहा है। अगर मैं अपने ऐप को स्थानीय जीएई ऐप सर्वर पर तैनात करना चाहता था, और फिर कोड चलाता हूं, तो यह ठीक काम करेगा, क्योंकि 'ApiProxy.getCurrentEnvironment() 'एनपीई नहीं फेंक देगा। इसलिए मुझे यह पता लगाने की आवश्यकता है कि परीक्षण उद्देश्यों के लिए जीएई के बाहर यह कैसे चल रहा है। – IAmYourFaja

+0

@DirtyMikeAndTheBoys मुझे पता है कि आप क्या करने की कोशिश कर रहे हैं। मैं सिर्फ इसके बारे में एक पूरी तरह से अलग तरीके से जाने का सुझाव दे रहा हूं। आपका कोड आपके नियंत्रण के बाहर एक स्थिर विधि पर निर्भर करता है जो परीक्षण में उत्पादन के मुकाबले अलग-अलग व्यवहार करता है। इससे आपके कोड को परीक्षण करना मुश्किल हो जाता है। मैं उस वर्ग के आधार पर समस्या का समाधान करूंगा जो आप नियंत्रित करते हैं। – NamshubWriter

0

आप 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

पिछले जवाब देने के लिए जोड़ने के लिए, अगर आप अपने इकाई परीक्षण मामले के भीतर एक धागा शुरू कर रहे हैं, कि जावा थ्रेड को एपीप्रोक्सी पर्यावरण सेट भी चाहिए।

अपनी कक्षा 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); 

    } 
} 

TEnvironment ऊपर यूआरएल में दी गई है।

आप एक स्थिर अनसेट पर्यावरण() भी बनाना चाहते हैं।

public void run() { 

    LocalServiceTestCase.setEnvironment(); 
सही धागे
2

आप मिल जाएगा से:

अपने इकाई परीक्षण मामले में, यदि आप एक नया जावा धागा शुरू कर दिया है, तो आप सिर्फ स्थिर विधि अपने रन विधि की शुरुआत में उपयोग कर सकते हैं स्टब्स, यदि आप निम्नलिखित लाइनों के साथ अपना लोकल सर्विस सर्विसस्टेलर सेट अप करते हैं।

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

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

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

इसके अलावा, helper.setUp() के बाद थ्रेडमेनगर का उपयोग करना याद रखें। – ZillGate

संबंधित मुद्दे