如何使用内容解析器/提供者测试类?

2023-12-21

我正在尝试测试查询内容解析器的类。

我想用MockContentResolver并嘲笑query方法。

问题是这个方法是最终的。我应该怎么办?使用模拟框架?模拟其他类?提前致谢。

public class CustomClass {

    private ContentResolver mContentResolver;

    public CustomClass(ContentResolver contentResolver) {
        mContentResolver = contentResolver;
    }

    public String getConfig(String key) throws NoSuchFieldException {
        String value = null;

            Cursor cursor = getContentResolver().query(...);
            if (cursor.moveToFirst()) {
                //...
            }
        //..
    }
}

下面是一个使用 getContentResolver().query 从内容提供者返回模拟数据的示例测试。

它应该适用于任何内容提供商,只需进行一些修改,但此示例模拟从联系人内容提供商返回的电话号码

以下是一般步骤:

  1. 使用 MatrixCursor 创建适当的光标
  2. 扩展 MockContentProvider 以返回创建的游标
  3. 使用 addProvider 和 setContentResolver 将提供程序添加到 MockContentResolver
  4. 将 MockContentResolver 添加到扩展的 MockContext
  5. 将上下文传递到被测试的类中

因为query是final方法,所以你不仅需要模拟MockContentProvider,还需要模拟MockContentResolver。否则在查询方法期间调用 acquireProvider 时会出现错误。

这是示例代码:

public class MockContentProviderTest extends AndroidTestCase{
    public void testMockPhoneNumbersFromContacts(){
        //Step 1: Create data you want to return and put it into a matrix cursor
        //In this case I am mocking getting phone numbers from Contacts Provider
        String[] exampleData = {"(979) 267-8509"}; 
        String[] examleProjection = new String[] { ContactsContract.CommonDataKinds.Phone.NUMBER};
        MatrixCursor matrixCursor = new MatrixCursor(examleProjection);
        matrixCursor.addRow(exampleData);

        //Step 2: Create a stub content provider and add the matrix cursor as the expected result of the query
        HashMapMockContentProvider mockProvider = new HashMapMockContentProvider();
        mockProvider.addQueryResult(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, matrixCursor);

        //Step 3: Create a mock resolver and add the content provider.
        MockContentResolver mockResolver = new MockContentResolver();
        mockResolver.addProvider(ContactsContract.AUTHORITY /*Needs to be the same as the authority of the provider you are mocking */, mockProvider);

        //Step 4: Add the mock resolver to the mock context
        ContextWithMockContentResolver mockContext = new ContextWithMockContentResolver(super.getContext());
        mockContext.setContentResolver(mockResolver);

        //Example Test 
        ExampleClassUnderTest underTest = new ExampleClassUnderTest();
        String result = underTest.getPhoneNumbers(mockContext);
        assertEquals("(979) 267-8509",result);
    }

    //Specialized Mock Content provider for step 2.  Uses a hashmap to return data dependent on the uri in the query
     public class HashMapMockContentProvider extends MockContentProvider{
         private HashMap<Uri, Cursor> expectedResults = new HashMap<Uri, Cursor>();
         public void addQueryResult(Uri uriIn, Cursor expectedResult){
             expectedResults.put(uriIn, expectedResult);
         }
         @Override
         public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder){
                return expectedResults.get(uri);
         } 
     }

     public class ContextWithMockContentResolver extends RenamingDelegatingContext {
            private ContentResolver contentResolver;
            public void setContentResolver(ContentResolver contentResolver){ this.contentResolver = contentResolver;}
            public ContextWithMockContentResolver(Context targetContext) { super(targetContext, "test");}
            @Override public ContentResolver getContentResolver() { return contentResolver; }
            @Override public Context getApplicationContext(){ return this; } //Added in-case my class called getApplicationContext() 
     }

     //An example class under test which queries the populated cursor to get the expected phone number 
     public class ExampleClassUnderTest{
         public  String getPhoneNumbers(Context context){//Query for  phone numbers from contacts
                String[] projection = new String[]{ ContactsContract.CommonDataKinds.Phone.NUMBER};
                Cursor cursor= context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, projection, null, null, null);
                cursor.moveToNext();
                return cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
         }
     }
}

如果您不想传递上下文:

如果你想让被测试的类中的 getContext() 返回它而不是传递它,你应该能够在你的 android 测试中重写 getContext() ,如下所示

@Override
 public Context getContext(){
    return new ContextWithMockContentResolver(super.getContext());   
 } 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用内容解析器/提供者测试类? 的相关文章

  • React Native 从 JavaScript 代码内部访问 strings.xml

    有没有办法访问当前值android app src main res values strings xml从 JavaScript 代码内部 我想为每个构建放置不同的端点 URL 但我什至无法检测到反应本机代码内的构建类型 而不必求助于 D
  • 如何重试已消耗的 Observable?

    我正在尝试重新执行失败的已定义可观察对象 一起使用 Retrofit2 和 RxJava2 我想在单击按钮时重试特定请求及其订阅和行为 那可能吗 service excecuteLoginService url tokenModel Ret
  • Android 30+ 中的视频捕获意图 - 只有所有者才能与待处理项目交互

    我正在尝试在我的应用程序上捕获视频 它可以在 android API 30 以下运行 但不能在 30 以上运行 似乎在 sdk 30 之后 android 不允许完全读取外部存储 作用域存储 我目前遇到这个错误 java lang Ille
  • 如何在android中获取Camera2 API的当前曝光

    In android hardware Camera旧的 我使用下面的代码获取当前曝光并获取它Camera Camera Parameters param mCamera getParameters currentExposure para
  • 是否可以将数组或对象添加到 Android 上的 SharedPreferences

    我有一个ArrayList具有名称和图标指针的对象 我想将其保存在SharedPreferences 我能怎么做 注意 我不想使用数据库 无论 API 级别如何 请检查SharedPreferences 中的字符串数组和对象数组 http
  • 何时使用模拟框架?

    因此 我正在使用模拟框架 Moq 进行单元测试 并且想知道何时应该使用模拟框架 以下两个测试之间的优点 缺点是什么 public class Tests Fact public void TestWithMock Arrange var r
  • java.lang.NoClassDefFoundError:org.apache.batik.dom.svg.SVGDOMImplementation

    我在链接到我的 Android LibGDX 项目的 Apache Batik 库时遇到了奇怪的问题 但让我们从头开始 在 IntelliJ Idea 中我有一个项目 其中包含三个模块 Main Android 和 Desktop 我强调的
  • 找不到处理意图 com.instagram.share.ADD_TO_STORY 的活动

    在我们的 React Native 应用程序中 我们试图让用户根据视图 组件中的选择直接将特定图像共享到提要或故事 当我们尝试直接使用 com instagram share ADD TO FEED 进行共享时 它以一致的方式完美运行 但是
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Android SIP 来电使用带有广播接收器的服务

    大家好 其实我正在尝试创建一个应用程序 支持基于 SIP 通过互联网进行音频呼叫 这里使用本机 sip 我遇到了来电问题 我已经完成了服务的注册部分 但是在接听电话时我无法接听电话 请帮助我 Service file package exa
  • 是否必须删除 Intent extra?

    这可能是一个愚蠢的问题 但是是否有一条规则规定消费活动必须显式删除 Intent 额外内容 或者只有在回收 Intent 对象时才如此 换句话说 如果我总是通过执行以下操作来链接到下一个活动 Intent i new Intent MyCu
  • 是否有 ADB 命令来检查媒体是否正在播放

    我想使用 ADB 命令检查根植于终端的外部设备中是否正在播放音频 视频 我无法找到任何 ADB 命令 如果有 我尝试过 adb shell dumpsys media player 我想要一个命令来指定视频是否正在运行 您可以使用以下命令查
  • 原色(有时)变得透明

    我正在使用最新的 SDK 版本 API 21 和支持库 21 0 2 进行开发 并且在尝试实施新的材料设计指南时遇到了麻烦 材料设计说我需要有我的primary color and my accent color并将它们应用到我的应用程序上
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • 在两个活动之间传输数据[重复]

    这个问题在这里已经有答案了 我正在尝试在两个不同的活动之间发送和接收数据 我在这个网站上看到了一些其他问题 但没有任何问题涉及保留头等舱的状态 例如 如果我想从 A 类发送一个整数 X 到 B 类 然后对整数 X 进行一些操作 然后将其发送
  • 工作流程系统中的单元/自动化测试

    您是否对像 K2 这样的复杂工作流程系统进行自动化测试 我们正在构建一个在 Sharepoint 2007 和 K2 之间进行广泛集成的系统 我什至无法想象从哪里开始自动化测试 因为工作流程涉及多个用户与 Sharepoint K2 工作流
  • Android:膨胀布局时出现 StackOverFlowError 和 InvokingTargetException

    首先 对不起我的英语 我在膨胀布局时有一个问题 我有一个自定义视图 从 LinearLayout 扩展而来 称为按钮帮助 我在名为的布局上使用该视图加载活动 我的以下代码在所有设备和模拟器上都能完美运行 但具有 QVGA 屏幕 例如 Sam
  • 捕获的图像分辨率太大

    我在做什么 我允许用户捕获图像 将其存储到 SD 卡中并上传到服务器 但捕获图像的分辨率为宽度 4608 像素和高度 2592 像素 现在我想要什么 如何在不影响质量的情况下获得小分辨率图像 例如我可以获取或设置捕获的图像分辨率为原始图像分
  • Crashlytics 出现 Android Studio 构建错误

    我正在尝试将 CrashLytics 与 Android Studio 和 gradle 一起使用 但出现一个令人困惑的错误 java lang NoSuchMethodError 我的 build gradle 是 buildscript
  • 按日期对 RecyclerView 进行排序

    我正在尝试按日期对 RecyclerView 进行排序 但我尝试了太多的事情 我不知道现在该尝试什么 问题就出在这条线上适配器 notifyDataSetChanged 因为如果我不放 不会显示错误 但也不会更新 recyclerview

随机推荐

  • Excel VBA 具有多个搜索条件并循环,直到找到所有不同的结果

    我对 VBA 非常陌生 并且截止日期非常短 因此如果我没有遵循所有论坛指南 我深表歉意 如果您能提供任何帮助 我将不胜感激 Goal 在 Sheet1 中搜索关键字 活动 站点地址 描述 所有者 估价 子类型 和 DATE B 一旦找到关键
  • 如何使用 UITableViewCell 附件复选标记取消选中所有行

    我有一个UITableView每行包含一个复选框 使用UITableViewCellAccessoryCheckmark 我不知道如何使用取消选中所有复选框didSelectRowAtIndexPath method void tableV
  • 如何通过弹出窗口获取输入并通过 javascript/jquery 将文本放入变量中

    我的页面上有一个按钮 单击时 应出现一个弹出框 允许用户输入文本 当按下 确定 提交 时 我的 jscript 将使用输入的数据执行一些功能 非常简单 但我就是不知道该怎么做 Thanks 以最简单的形式 您可以使用提示 问题 默认 摘自w
  • 使用真正的随机盐或用户名盐加胡椒进行密码哈希?

    考虑以下两种方法 hashedPassword hash trulyRandomSalt password 其中 hashedPassword 和 trueRandomSalt 存储在数据库中 hashedPassword hash app
  • 无法连接到应用程序正在侦听的 Docker 容器端口

    我想运行 Jenkins 但为了演示问题 我在 Ubuntu 15 10 中运行 netcat 服务器容器 Docker version 1 6 2 build 7c8fca2 这是我的 Dockerfile FROM ubuntu CMD
  • 使用 pandas dataframe 的内存泄漏

    我在用pandas DataFrame在多线程代码中 实际上是DataFrame called Sound 我注意到我有内存泄漏 因为我的程序的内存使用量逐渐增加超过 1000 万 最终达到计算机内存的 100 并崩溃 I used obj
  • 在 dart 中使用 source_gen 为一系列已解析文件生成一个文件

    我有一个创建迷你反射系统所需的模型列表 我分析了可序列化包并了解如何为每个文件创建一个生成的文件 但是 我找不到如何为大量文件创建一个文件 那么 如何使用 source gen 为一系列文件动态生成一个文件呢 Example Files用户
  • 使会话无效

    我有一个基于 jsp servlet 的应用程序 会话时间超过 30 分钟 我想在有人有意或无意关闭浏览器窗口时立即使会话无效 操作系统关闭 从tast管理器关闭 断电 我可以对此进行检查并使会话无效吗 无法处理这种情况 有一些浏览器提供此
  • 在 JavaScript 中将“'”替换为“”

    我的字符串是这样的 temp SE019 SR132 SC123 我使用如下函数 temp replace 但结果将是 SE019 SR132 SC123 仅删除第一个引号 我需要删除所有引号 使用正则表达式文字g 对于全局 意味着匹配al
  • 无法导入设置;不在系统路径上

    我正在尝试让 Django 使用 virtualenv 工作 我已经上线了 hello world 页面 但是 现在似乎出了问题 因为我的大多数命令都给出了有关 myProject settings 的相同错误 myenv user min
  • 如何使用 Azure 表存储选择 RowKey 范围?

    我想使用主键查询我的天蓝色表存储 另外我想检查我的 RowKey 是否在一个范围内 例如范围 02001 到 02999 有人能告诉我该怎么做吗 我了解如何用简单的方法查询 PK where fooEntiy PartitionKey pa
  • 如何在Python中配置装饰器

    我正在尝试使用 Thespian https thespianpy com doc https thespianpy com doc 一个用于演员模型的 Python 库 特别是我正在尝试使用 剧团 功能 据我了解 剧团装饰器充当调度程序
  • 合并 GitHub 帐户 - 贡献和统计数据

    我想合并我的两个 GitHub 帐户 这意味着将存储库所有权转移到一个帐户 并删除另一个帐户 根据https help github com articles transferring a repository https help git
  • 新的时间轴,如按钮行为

    在新样式的页面选项卡上 赞 按钮不再刷新页面 这打破了 Like gates 的现有工作流程 即在服务器上检查签名的请求 就像页面一样 页面刷新 繁荣 选项卡现在更新为 喜欢 状态 当用户单击新的 赞 按钮时 是否会触发任何类型的事件 或者
  • 为什么 Mongoose 不验证空文档?

    假设我有一个非常简单的模式 带有一个始终返回 false 的自定义验证函数 var MofoSchema new mongoose Schema name String MofoSchema path name validate funct
  • 60 秒后阻止操作调用超时 - 如何访问结果?

    我正在尝试调用 Apache OpenWhisk 操作 使用 JavaScript SDK 作为远程函数 我想等待函数结果可在我的应用程序中使用 这通常通过使用阻塞调用来处理 例如 ow actions invoke name blocki
  • 多语言网站 - 如何设置所需的默认语言?

    我用 joomla 多语言制作网站 塞尔维亚语和英语 我正在使用 joomla 3 3 3 和 joomla 内置对多语言的支持 但我想将塞尔维亚语设置为默认语言 因此 当用户访问我的网站时 默认情况下总是使用塞尔维亚语 怎么做 谢谢 您必
  • 将日期添加到日期对象[重复]

    这个问题在这里已经有答案了 可能的重复 如何在今天的日期上添加天数 https stackoverflow com questions 3818193 how to add number of days to todays date 我很困
  • 安装 libCurl - ruby​​ 1.9.3 ..rails 3.2.12 ..Windows

    所以 我正在尝试让 feedzirra 启动并运行 ruby 1 9 3p448 Rails 3 2 12 我去了http curl haxx se download html Win32 http curl haxx se downloa
  • 如何使用内容解析器/提供者测试类?

    我正在尝试测试查询内容解析器的类 我想用MockContentResolver并嘲笑query方法 问题是这个方法是最终的 我应该怎么办 使用模拟框架 模拟其他类 提前致谢 public class CustomClass private