UnsupportedOperationException异常同时呼吁getShared preferences()的单元测试 [英] UnsupportedOperationException while calling getSharedPreferences() from unit test

查看:297
本文介绍了UnsupportedOperationException异常同时呼吁getShared preferences()的单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实现了内容提供商,从安装在网络服务中检索数据。 内容提供商需要从共享preferences需要的参数(用户凭证,应用程序的名称,等等。)

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, app name, etc.)

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

我使用的单元测试此内容提供商:

I use unit test for this Content provider:


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());
    }
}

在执行单元测试。在抛出异常:

During execution of the unit test. The exception is thrown:


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)
   ...

有谁知道如何共享preferences传递给MockContext?我应该用其他的方式,如果我测试的内容提供商在需要上下文?

Does anybody know how to pass Shared Preferences to the MockContext? Should I use other approach if I need Context during testing Content Provider?

推荐答案

您必须注入上下文扩展 MockContext 使用<一个href="http://developer.android.com/reference/android/test/AndroidTestCase.html#setContext%28android.content.Context%29">AndroidTestCase.setContext()并覆盖至少 getPackageName() getShared preferences()

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

不幸的是,这是不可能的注入 MockContext ProviderTestCase2 因为setContext()没有兑现。然后,该解决方案是覆盖设置()不是调用超级方法。

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;

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);
        }
    }

}

这篇关于UnsupportedOperationException异常同时呼吁getShared preferences()的单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆