gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:11:18 24 4
gpt4 key购买 nike

我正在整合 a custom widget进入我的项目。它使用自定义属性并使 Robolectric 崩溃。据我所知,custom attributes aren't supported yet .注意:构造函数是“敌对的”,因为它会在构造时抛出异常,但我现在已经将它们注释掉了。

崩溃日志

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

Caused by: java.lang.ClassCastException: com.blah.support.shadows.ShadowMultiDirectionSlidingDrawer cannot be cast to com.xtremelabs.robolectric.shadows.ShadowView at com.xtremelabs.robolectric.Robolectric.shadowOf(Robolectric.java:857) at com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:70) at android.view.ViewGroup.addView(ViewGroup.java) at com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:60) at android.view.ViewGroup.addView(ViewGroup.java) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.addToParent(ViewLoader.java:217) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:180) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:150) at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:153) at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102) ... 29 more

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

有人建议a hack of placing the java file in a android package ,但我不确定它是否适用于我的情况。正如这个答案所建议的那样,自定义小部件位于与我的 com.blah 结构平行的包“android”中。

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

影子类

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

在测试框架支持之前,这是解决崩溃问题的正确方法吗?是我的影子做错了什么还是遗漏了什么?

最佳答案

所以我用一种简单的方法解决了这个问题。我没有将 View 扩充为我的 main.xml 的一部分,而是将它放在一个单独的布局文件中。在我的 Activity 的构造函数中,我在一个 protected 函数中扩充了布局。在我的测试类中,我扩展了被测类,而不是膨胀 View 元素,我使用 bool 值来跟踪调用的函数。

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

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

关于android - 在使用 Robolectric 测试 Android 应用程序时,如何创建影子类来解决与自定义属性相关的崩溃问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11695774/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com