Skip to content Skip to sidebar Skip to footer

Unsupportedoperationexception While Calling Getsharedpreferences() From Unit Test

I've implemented Content Provider that retrieves data from a service installed on network. The content provider takes required parameters from shared preferences (user credentials,

Solution 1:

You have to inject a Context that extends MockContext using AndroidTestCase.setContext() and overrides at least getPackageName() and getSharedPreferences().

Unfortunately, it's not possible to inject a MockContext to ProviderTestCase2 because setContext() is not honored. Then, the solution is to override setUp() not invoking the super method.

package com.example.aatg.ps.test;

import android.test.ProviderTestCase2;

import com.example.aatg.ps.ProviderSample;

publicclassProviderSampleTestsextendsProviderTestCase2<ProviderSample> {

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

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

    @OverrideprotectedvoidsetUp()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 = newResolverRenamingMockContext(getContext());
        mProvider = mProviderClass.newInstance();
        assertNotNull(mProvider);
        mProvider.attachInfo(mProviderContext, null);
        mProviderContext.addProvider(mProviderAuthority, mProvider);
    }


    @Overridepublic ProviderSample getProvider() {
        return mProvider;
    }

    protectedvoidtearDown()throws Exception {
        super.tearDown();
    }

    publicvoidtestProviderSampleCreation() {
        ProviderSampleprovider= getProvider();
        assertNotNull(provider);
    }
}

And this is 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
 *
 */publicclassResolverRenamingMockContextextendsIsolatedContext {

    /**
     * The renaming prefix.
     */privatestaticfinalStringPREFIX="test.";


    /**
     * The resolver.
     */privatestaticfinalMockContentResolverRESOLVER=newMockContentResolver();

    /**
     * Constructor.
     * @param context 
     */publicResolverRenamingMockContext(Context context) {
        super(RESOLVER, newDelegatedMockContext(context));
    }

    public MockContentResolver getResolver() {
        return RESOLVER;
    }

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

    /**
     * The DelegatedMockContext.
     *
     */privatestaticclassDelegatedMockContextextendsMockContext {

        private Context mDelegatedContext;

        publicDelegatedMockContext(Context context) {
            mDelegatedContext = context;
        }

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

}

Solution 2:

just extend AndroidTestCase instead of ProviderTestCase2 AND use getContext()

Solution 3:

You can refactor your Content Provider to push all uses of Shared Preferences into a MyHelper class.

The default MyHelper implementation can use Shared Preferences much like you're using it now, and returns the values you need through getters.

During testing, you can inject a special MyHelper implementation, one that doesn't use Shared Preferences. Perhaps it's called TestingHelper it just returns constants defined by the tests.

For example, in ResearchProviderTest:

@OverrideprotectedvoidsetUp()throws Exception {
    // set up normallysuper.setUp();

    // inject a special helper for testingMyProviderprovider= (MyProvider) getProvider();
    provider.setHelper(newTestingHelper());
}

Post a Comment for "Unsupportedoperationexception While Calling Getsharedpreferences() From Unit Test"