Unsupportedoperationexception While Calling Getsharedpreferences() From Unit Test
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"