2011-03-11 27 views
10

से getSharedPreferences() को कॉल करते समय असमर्थितऑपरेशन अपवाद, मैंने सामग्री प्रदाता को लागू किया है जो नेटवर्क पर स्थापित सेवा से डेटा पुनर्प्राप्त करता है। सामग्री प्रदाता साझा वरीयताओं से आवश्यक पैरामीटर (उपयोगकर्ता क्रेडेंशियल ऐप्लिकेशन का नाम, आदि)यूनिट परीक्षण

SharedPreferences settings = getContext().getSharedPreferences(NET_PREFS, 0); 

लेता है मैं इस सामग्री प्रदाता के लिए इकाई परीक्षण का उपयोग करें:


public class ResearchProviderTest extends ProviderTestCase2<MyProvider>{ 

    public ResearchProviderTest() {  
     super(MyProvider.class, MyProvider.CONTENT_AUTHORITY); 
    } 

    public void testInsert() { 

     ContentValues values = new ContentValues();   
     values.put(QueryFields.FIELD_QUERY_TEXT, "query"); 

     Uri newUri = getMockContentResolver().insert(MyProvider.CONTENT_URI, values); 

     Cursor readMessagesCursor = getMockContentResolver().query(
       newUri , 
         new String[] { FIELD_SR_TITLE }, 
         null, null, null); 
     assertTrue("The cursor should contain some entries", readMessagesCursor.moveToFirst()); 
    } 
} 

इकाई परीक्षण के निष्पादन के दौरान। अपवाद फेंक दिया गया है:


java.lang.UnsupportedOperationException 
    at android.test.mock.MockContext.getSharedPreferences(MockContext.java:127) 
    at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:146) 
    at android.content.ContextWrapper.getSharedPreferences(ContextWrapper.java:146) 
    at com.company.mobile.android.net.RemoteExecutor.retrieveCredentials(RemoteExecutor.java:171) 
    at com.company.mobile.android.net.service.Adapter.executeSearch(Adapter.java:33) 
    at com.company.mobile.android.provider.MyProvider.insert(MyProvider.java:167) 
    at android.content.ContentProvider$Transport.insert(ContentProvider.java:174) 
    ... 

क्या कोई जानता है कि MockContext में साझा प्राथमिकताओं को कैसे पास किया जाए? यदि मुझे सामग्री प्रदाता परीक्षण के दौरान संदर्भ की आवश्यकता है तो क्या मुझे अन्य दृष्टिकोण का उपयोग करना चाहिए?

उत्तर

6

आप एक Context कि MockContext फैली AndroidTestCase.setContext() का उपयोग कर और कम से कम getPackageName() और getSharedPreferences() ओवरराइड करता है इंजेक्षन करने के लिए है।

दुर्भाग्यवश, MockContext से ProviderTestCase2 को इंजेक्ट करना संभव नहीं है क्योंकि setContext() को सम्मानित नहीं किया जाता है। फिर, समाधान सुपर विधि का आह्वान न करने पर setUp() ओवरराइड करना है।

package com.example.aatg.ps.test; 

import android.test.ProviderTestCase2; 

import com.example.aatg.ps.ProviderSample; 

public class ProviderSampleTests extends ProviderTestCase2<ProviderSample> { 

    private ResolverRenamingMockContext mProviderContext; 
    private Class<ProviderSample> mProviderClass; 
    private ProviderSample mProvider; 
    private String mProviderAuthority; 

    public ProviderSampleTests() { 
     super(ProviderSample.class, ProviderSample.AUTHORITY); 
     setName("ProviderSampleTests"); 
     mProviderClass = ProviderSample.class; 
     mProviderAuthority = ProviderSample.AUTHORITY; 
    } 

    @Override 
    protected void setUp() throws Exception { 
     // We should not invoke super.setUp() here to avoid the UnsupportedOperationException. 
     //super.setUp(); 

     // This is needed to support getSharedPreferences() in ProviderSample.onCreate() 
     mProviderContext = new ResolverRenamingMockContext(getContext()); 
     mProvider = mProviderClass.newInstance(); 
     assertNotNull(mProvider); 
     mProvider.attachInfo(mProviderContext, null); 
     mProviderContext.addProvider(mProviderAuthority, mProvider); 
    } 


    @Override 
    public ProviderSample getProvider() { 
     return mProvider; 
    } 

    protected void tearDown() throws Exception { 
     super.tearDown(); 
    } 

    public void testProviderSampleCreation() { 
     ProviderSample provider = getProvider(); 
     assertNotNull(provider); 
    } 
} 

और यह ResolverRenamingMockContext है:

package com.example.aatg.ps.test; 

import java.io.File; 

import android.content.ContentProvider; 
import android.content.Context; 
import android.content.SharedPreferences; 
import android.content.res.Resources; 
import android.test.IsolatedContext; 
import android.test.mock.MockContentResolver; 
import android.test.mock.MockContext; 

/** 
* @author diego 
* 
*/ 
public class ResolverRenamingMockContext extends IsolatedContext { 

    /** 
    * The renaming prefix. 
    */ 
    private static final String PREFIX = "test."; 


    /** 
    * The resolver. 
    */ 
    private static final MockContentResolver RESOLVER = new MockContentResolver(); 

    /** 
    * Constructor. 
    * @param context 
    */ 
    public ResolverRenamingMockContext(Context context) { 
     super(RESOLVER, new DelegatedMockContext(context)); 
    } 

    public MockContentResolver getResolver() { 
     return RESOLVER; 
    } 

    public void addProvider(String name, ContentProvider provider) { 
     RESOLVER.addProvider(name, provider); 
    } 

    /** 
    * The DelegatedMockContext. 
    * 
    */ 
    private static class DelegatedMockContext extends MockContext { 

     private Context mDelegatedContext; 

     public DelegatedMockContext(Context context) { 
      mDelegatedContext = context; 
     } 

     @Override 
     public SharedPreferences getSharedPreferences(String name, int mode) { 
      return mDelegatedContext.getSharedPreferences(PREFIX + name, mode); 
     } 
    } 

} 
+0

संदर्भ इंजेक्शन एक मुख्य समस्या है। मुझे संदर्भ इंजेक्ट करने का कोई तरीका नहीं मिला – Glaxalg

1

सिर्फ ProviderTestCase2 के बजाय AndroidTestCase का विस्तार और उपयोग getContext()

0

आप अपनी सामग्री एक MyHelper वर्ग में साझा पसंद के सभी उपयोगों पुश करने के लिए प्रदाता refactor कर सकते हैं।

डिफ़ॉल्ट MyHelper कार्यान्वयन साझा प्राथमिकताओं का उपयोग कर सकता है जैसे कि आप इसे अभी उपयोग कर रहे हैं, और गेटर्स के माध्यम से आपको आवश्यक मूल्यों को वापस कर सकते हैं।

परीक्षण के दौरान, आप एक विशेष MyHelper कार्यान्वयन इंजेक्ट कर सकते हैं, जो साझा प्राथमिकताओं का उपयोग नहीं करता है। शायद इसे TestingHelper कहा जाता है, यह केवल परीक्षणों द्वारा परिभाषित स्थिरांक देता है।

उदाहरण के लिए, ResearchProviderTest में:

@Override 
protected void setUp() throws Exception { 
    // set up normally 
    super.setUp(); 

    // inject a special helper for testing 
    MyProvider provider = (MyProvider) getProvider(); 
    provider.setHelper(new TestingHelper()); 
} 
संबंधित मुद्दे