使用 Robolectric 测试 Android 应用程序时,如何创建影子类来解决与自定义属性相关的崩溃问题?

2023-11-21

我正在整合自定义小部件进入我的项目。它使用自定义属性并且导致 Robolectric 崩溃。据我收集的信息,尚不支持自定义属性。注意:构造函数是“敌对的”,因为它在构造时抛出异常,但我现在已经将它们注释掉了。

崩溃日志

java.lang.RuntimeException:错误膨胀布局/主 在 com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:106) 在 com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:82) 在 com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:86) 在 com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:377) 在 com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate (ShadowLayoutInflater.java:43) 在 com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate (ShadowLayoutInflater.java:48) 在 android.view.LayoutInflater.inflate(LayoutInflater.java) 在 com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:101) 在 android.app.Activity.setContentView(Activity.java) 在 com.blah.MainActivity.onCreate(MainActivity.java:17) 在 com.blah.MainActivityTest.setUp(MainActivityTest.java:29) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 在 org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)

引起原因:java.lang.ClassCastException:com.blah.support.shadows.ShadowMultiDirectionSlidingDrawer无法转换为com.xtremelabs.robolectric.shadows.ShadowView 在 com.xtremelabs.robolectric.Robolectric.shadowOf(Robolectric.java:857) 在 com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:70) 在 android.view.ViewGroup.addView(ViewGroup.java) 在 com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:60) 在 android.view.ViewGroup.addView(ViewGroup.java) 在 com.xtremelabs.robolectric.res.ViewLoader$ViewNode.addToParent(ViewLoader.java:217) 在 com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:180) 在 com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:150) 在 com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:153) 在 com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102) ... 29 更多

我正在尝试解决这个问题,因为我不太关心测试这个小部件。基本上我希望我的测试不会崩溃并验证视图元素是否出现在屏幕上。

有人建议将java文件放入android包中的技巧,但我不确定它是否适用于我的情况。正如这个答案所建议的,自定义小部件位于“android”包中,它与我的 com.blah 结构平行。

我创建了小部件的影子来解决敌意问题(但目前我只是注释掉抛出的异常)。最初,我想绕过构造函数中正在完成的工作,因为它依赖于 Robolectric 未正确报告的属性。影子构造函数正在被调用,但它会继续执行正常的构造函数。有没有办法绕过额外的建设?

影子类

@Implements (MultiDirectionSlidingDrawer.class)
public class ShadowMultiDirectionSlidingDrawer
{
    public void __constructor__( Context context, AttributeSet attrs )
    {
    }

    public void __constructor__( Context context, AttributeSet attrs, int defStyle )
    {
    }
}

自定义测试运行器

public class CustomTestRunner extends RobolectricTestRunner 
{
    public CustomTestRunner( Class<?> testClass ) throws InitializationError
    {
        super( testClass );
        addClassOrPackageToInstrument("android");
    }

    @Override
    protected void bindShadowClasses()
    {
        super.bindShadowClasses();
        Robolectric.bindShadowClass( ShadowMultiDirectionSlidingDrawer.class );
    }
}

在测试框架支持这一点之前,这是解决崩溃问题的正确方法吗?我是否对我的影子做错了什么,或者我错过了什么?


所以我用一个简单的方法解决了这个问题。我没有将视图作为 main.xml 的一部分进行扩展,而是将其放入单独的布局文件中。在我的活动的构造函数中,我在受保护的函数中膨胀了布局。在我的测试类中,我扩展了被测类,并且没有膨胀视图元素,而是使用布尔值来跟踪所调用的函数。

MainActivity.java

public class MainActivity extends FragmentActivity
{
    @Override
    public void onCreate( Bundle savedInstanceState )
    {
        super.onCreate( savedInstanceState );
        setContentView( R.layout.main );
        addOptionsShade();
    }

    protected void addOptionsShade()
    {
        ViewGroup viewGroup = (ViewGroup) findViewById( R.id.main_view );
        View view = getLayoutInflater().inflate( R.layout.options_shade, null );
        viewGroup.addView( view );
    }
}

MainActivityTest.java

@Test
public void shouldHaveOptionsShade() throws Exception
{
    assertTrue( mainActivity.hostileLibraryWasCalled );
}

class TestMainActivity extends MainActivity
{
    boolean hostileLibraryWasCalled = false;

    @Override
    protected void addOptionsShade()
    {
        hostileLibraryWasCalled = true;
    }
}

我删除了影子类和绑定,并将库放回到一个合理的位置(不在 android 包中)。

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

使用 Robolectric 测试 Android 应用程序时,如何创建影子类来解决与自定义属性相关的崩溃问题? 的相关文章

随机推荐

  • 如何在具有动态键值对的javascript中解析json? [复制]

    这个问题在这里已经有答案了 我想在 JavaScript 中解析 JSON 字符串 响应是这样的 var response 1 10 2 10 如何从这个 json 中获取每个键和值 我正在这样做 var obj parseJSON res
  • 在 php 中取消设置变量

    我刚刚通过 php 手册阅读了有关 unset 变量的内容 php手册说 unset 销毁指定的变量 这个 def 看起来很完美 直到我遇到静态变量 如果在函数内部 unset 静态变量 则 unset 仅在函数其余部分的上下文中销毁该变量
  • 我可以使用 link_to 链接图像和文本吗

    好吧 我正在使用 font awesome rails gem 我已经习惯了 Rails 之外的很棒的字体 但我想它在 Rails 社区中并不那么受欢迎 安装后 它会使用以下格式创建图标 i class nameoftheicon i 我想
  • 将流步骤添加到在 AWS EMR 5.0 上运行的 boto3 中的 MR 作业

    我正在尝试将用 python 编写的几个 MR 作业从 AWS EMR 2 4 迁移到 AWS EMR 5 0 到目前为止 我使用的是 boto 2 4 但它不支持 EMR 5 0 所以我正在尝试转向 boto3 早些时候 在使用 boto
  • Spring 4 - addResourceHandlers 不解析静态资源

    我的maven spring项目目录结构如下所示 我正在使用基于 Spring 4 注释的配置 我如下配置资源 我尝试了许多 Stackoverflow 问题和其他网站中建议的方法 Spring 4加载静态资源 http imwill co
  • 在 Symfony/SonataUserBundle 设置中调用 setCurrentUri 方法失败

    我正在尝试使用 SonataUserBundle 设置 Symfony 用户注册和登录工作正常 当我尝试拨打电话时 profile查看 但是我收到以下错误 Attempted to call method setCurrentUri on
  • pytest中的测试用例执行顺序

    我正在使用 pytest 我的目录中有两个文件 在其中一个文件中 有一个长时间运行的测试用例 会生成一些输出 在另一个文件中 有一个读取该输出的测试用例 如何保证两个测试用例的正确执行顺序 除了按照正确的顺序将测试用例放在同一个文件中之外
  • lambda 中的“变量阴影”警告(未捕获时)

    让我们考虑一下这段代码 int main int a 1 auto f1 a int a 10 return a auto f2 int a 100 return a return a f1 f2 使用标志时 Wshadow使用 gcc 在
  • svg 超出屏幕,渲染了吗?

    场景 我有可以放大和缩小的 SVG 图像 根据缩放 我将在可见部分显示更多 更少的细节 问题是 我应该照顾吗 not显示当前不可见 屏幕外 的部分的详细信息 或者渲染引擎足够智能 可以跳过 剪辑 这些部分before它们被渲染了吗 是的 浏
  • 使用 Python 将 Geojson 转换为 shapefile

    我正在尝试将 geojson 文件转换为 shapefile 我正在尝试这种方式 我对Python很陌生 所以它可能是不正确的 import urllib geojson gdal url http ig3is grid unep ch i
  • gradle 中的多风格编译依赖项

    有没有办法在 Android Studio build gradle 中通过多种风格编译依赖项 我有 2 个风味组 每组有 2 个变体 在 4 种可能的组合中 我希望仅当我既是最新版本又是免费版本时才能依赖库 latestCompile 或
  • C#:使用 PDFsharp 创建 PDF 表单 (AcroForm)

    如何将 PDF 表单元素添加到 PDFsharpPdfPage object 我知道 AcroForm 是可填写表单的 PDF 元素的最佳格式 但 PDFsharp 库似乎不允许您创建 AcroForm 对象的实例 我已经能够使用 PDFs
  • TypeNameHandling=auto 的 IEnumerable 的 Json.Net 序列化

    根据Json Net 文档 all IEnumerable类型应序列化为 json 数组 所以我期待以下课程 public class MyClass public IEnumerable
  • 机架抛出 EOFError(内容主体错误)

    我们使用 Ruby 2 1 2 Rails 3 2 19 和 JQuery 1 11 未使用资产管道 因此不使用 JQuery ujs 但显式使用相关的 Rails js 对于大多数用户来说 JQuery 和其他相关的常见插件是从 Goog
  • 不在 ListView 中滚动时自动隐藏滚动条

    在新的官方 Twitter 应用程序中 应用程序使用的所有 ListView 中的滚动条都会隐藏 除非用户滚动列表 当您开始滚动时 会出现滚动条 当您停止时 它们会以动画方式淡出 直到完全消失 我似乎在文档中找不到任何表明这是标准功能的内容
  • 在Python中清除终端[重复]

    这个问题在这里已经有答案了 是否存在任何标准的 自带电池 方法来从Python脚本中清除终端屏幕 或者我必须去诅咒 库 而不是单词 一个简单且跨平台的解决方案是使用clsWindows 上的命令 或clear在 Unix 系统上 与使用os
  • 有没有办法增加构面中 strip.text 栏的高度?

    我希望顶部的灰色条更宽 例如 其边缘距离字母的顶部和底部稍远一些 strip text A B C 等 我本以为行高会起到填充的作用 但事实并非如此 ggplot diamonds aes carat price fill density
  • 重置 Entity Framework 7 迁移

    我正在使用 Entity Framework 7 beta 5 我从带有用户管理的 mvc 模板开始 在我的试验过程中 我添加了几次迁移 现在我想删除我的数据库 创建一个新的初始迁移并用它生成一个新的干净数据库 然而 据我所知 dnx ef
  • 在 .net core 3+ 中实际上做了什么?

    最近 我读到使用ASP NET Core共享框架我想知道 它在幕后是如何工作的 添加时是否有任何我应该考虑的缺点或警告
  • 使用 Robolectric 测试 Android 应用程序时,如何创建影子类来解决与自定义属性相关的崩溃问题?

    我正在整合自定义小部件进入我的项目 它使用自定义属性并且导致 Robolectric 崩溃 据我收集的信息 尚不支持自定义属性 注意 构造函数是 敌对的 因为它在构造时抛出异常 但我现在已经将它们注释掉了 崩溃日志 java lang Ru