【问题标题】:Android Lollipop Appcompat problems running with Robolectric与 Robolectric 一起运行的 Android Lollipop Appcompat 问题
【发布时间】:2014-10-22 16:52:22
【问题描述】:

自从 Android Lollipop 推出以来,使用新的 Appcompat 支持库时,我无法运行 Robolectic 测试。我关注了:

我目前的进度可以在这里查看:https://github.com/fada21/android-tdd-bootstrap

我的配置(蒸馏)是:

android {
  compileSdkVersion 21
  buildToolsVersion "21.0.1"

defaultConfig {
  applicationId "com.fada21.android.bootstrap"
  minSdkVersion 15
  targetSdkVersion 21

...

dependencies {
  compile fileTree(dir: 'libs', include: ['*.jar'])
  compile 'com.android.support:support-v4:21.0.0'
  compile 'com.android.support:appcompat-v7:21.0.0'

...

androidTestCompile('org.robolectric:robolectric:2.4-SNAPSHOT') {

我在这里提出了一个问题:https://github.com/robolectric/robolectric/issues/1332(查看此处了解更多详细信息)。

这是我遇到的错误:

java.lang.RuntimeException: Could not find any resource  from reference ResName{com.fada21.android.bootstrap:style/Theme_AppCompat_Light_NoActionBar} from style StyleData{name='AppTheme', parent='Theme_AppCompat_Light_NoActionBar'} with theme null
at org.robolectric.shadows.ShadowAssetManager$StyleResolver.getParent(ShadowAssetManager.java:456)
at org.robolectric.shadows.ShadowAssetManager$StyleResolver.getAttrValue(ShadowAssetManager.java:394)
at org.robolectric.shadows.ShadowResources.getOverlayedThemeValue(ShadowResources.java:297)
at org.robolectric.shadows.ShadowResources.findAttributeValue(ShadowResources.java:286)
at org.robolectric.shadows.ShadowResources.attrsToTypedArray(ShadowResources.java:189)
at org.robolectric.shadows.ShadowResources.access$000(ShadowResources.java:48)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:494)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:489)
at org.robolectric.shadows.ShadowResources$ShadowTheme.obtainStyledAttributes(ShadowResources.java:484)
at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java)
at android.content.Context.obtainStyledAttributes(Context.java:380)
at android.support.v7.app.ActionBarActivityDelegate.onCreate(ActionBarActivityDelegate.java:143)
at android.support.v7.app.ActionBarActivityDelegateBase.onCreate(ActionBarActivityDelegateBase.java:139)
at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:123)
at com.fada21.android.bootstrap.HomeActivity.onCreate(HomeActivity.java:28)
at android.app.Activity.performCreate(Activity.java:5133)
at org.fest.reflect.method.Invoker.invoke(Invoker.java:112)
at org.robolectric.util.ActivityController$1.run(ActivityController.java:113)
at org.robolectric.shadows.ShadowLooper.runPaused(ShadowLooper.java:265)
at org.robolectric.util.ActivityController.create(ActivityController.java:110)
at org.robolectric.util.ActivityController.create(ActivityController.java:120)
at com.fada21.android.bootstrap.HomeActivityTest.testActivityNotNull(HomeActivityTest.java:24)

【问题讨论】:

  • 我目前正在关注此线程github.com/robolectric/robolectric/issues/…。有同样的问题。
  • 是的,我开始了这个话题。 @loeschg 你试过评论中提到的这个 ShadowSupportMenuInflater 吗?
  • 我确实尝试过...我想。我打算明天重点看看。感谢您为我指明方向!
  • 我一直在 github 和这里关注这个帖子。各位有没有想出一个可行的解决方案?我有同样的事情,我所有的活动都使用了试图使用 Theme.AppCompat.Light 的 ActionBarActivity。线程似乎指出它将在 3.0 版中修复。你们有没有找到另一种方法来使用 Robolectric 测试这些活动?我在这里尝试了答案,并在 github 线程中尝试了一堆解决方案,但没有骰子。
  • @lazypig 我已经发布了一个解决方案。你能试一试,告诉我这对你有用吗?

标签: android robolectric android-appcompat


【解决方案1】:

注意:截至 2015 年 7 月 7 日,Roboelectric 3.0 已发布。它解决了相关问题,不再需要此答案。

旧答案:

在 Robolectric 3.0 出来之前,这里有一个修复。

#/app/src/main/res/values/styles.xml
<resources>

    //<!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        //<!-- Customize your theme here. -->
    </style>


    //<!-- Hack for Robolectric to run with appcompat.v7 -->
    <style name="RoboAppTheme" parent="@android:style/Theme.Holo.Light.DarkActionBar">
        //<!-- Customize your theme here. -->
    </style>

</resources>

然后调整你的自定义 RobolectricRunner 类

public class MyRobolectricTestRunner extends RobolectricTestRunner {
    private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;

    public MyRobolectricTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override
    protected AndroidManifest getAppManifest(Config config) {
        String manifestProperty = "../app/src/main/AndroidManifest.xml";
        String resProperty = "../app/src/main/res";
        return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty)) {
            @Override
            public int getTargetSdkVersion() {
                return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
            }

            @Override
            public String getThemeRef(Class<? extends Activity> activityClass) {
                return "@style/RoboAppTheme";
            }
        };
    }
}

基本上我们只是告诉 JVM 使用不同的应用程序主题。然后像平常使用@RunWith(MyRobolectricTestRunner.class) 一样使用这个TestRunner。

注意: 这解决了仅extend Activity 的活动,extend ActionBarActivity 的活动会出现其他相同类型的问题

编辑:截至 2015 年 4 月 7 日,Robolectric 3.0-snapshot 版本可用,占 ActionBarActivity。更多信息请参见 cmets 中的链接

【讨论】:

  • 对于从 ActionBarActivity 扩展的活动有什么可以做的吗?我所有的活动都来自 ActionBarActivity
  • @ZakTaccardi 我还没有深入了解它,我只是发布了修复我的用例的解决方案。你可以试试Robolectric 3.0-snapshot 我相信它支持ActionBarActivity?我不太确定。你将不得不做更多的挖掘。对不起。 Here is some more information
  • Robolectric 3.0 是您仍然需要 Robolectric 的最佳选择。我认为使用新的 android-testing 库是更好的解决方案。
  • 我正在使用 3.0 并且仍然遇到此错误,所以如果他们已修复它,则修复已回滚。
  • 是的,在 3.4.2 上仍然可以看到这个
【解决方案2】:

在与清单相同的 hierarki 级别添加一个 project.properties 文件,其内容如下:

android.library.reference.1=../../build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.0.0

确保 appcompat 版本与您的 gradle 文件中的版本相同。

【讨论】:

    【解决方案3】:

    使用这个自定义 RobolectricTestRunner 解决了我遇到的类似问题。这也意味着您不需要在每个测试中都使用 @Config(emulateSdk = 18)。

    替换:@RunWith(RobolectricTestRunner.class)

    with:@RunWith(MyRobolectricTestRunner.class) 在你所有的 Robolectric 测试中

    public class MyRobolectricTestRunner extends RobolectricTestRunner {
    
        public MyRobolectricTestRunner(Class<?> testClass) throws InitializationError {
            super(testClass);
        }
    
        @Override
        protected AndroidManifest getAppManifest(Config config) {
            String manifestProperty = System.getProperty("android.manifest");
            if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
                String resProperty = System.getProperty("android.resources");
                String assetsProperty = System.getProperty("android.assets");
                CustomAndroidManifest androidManifest = new CustomAndroidManifest(
                        Fs.fileFromPath(manifestProperty),
                        Fs.fileFromPath(resProperty),
                        Fs.fileFromPath(assetsProperty));
                androidManifest.setPackageName("com.justyoyo");
                return androidManifest;
            }
            return super.getAppManifest(config);
        }
    
        private static class CustomAndroidManifest extends AndroidManifest {
    
            private static final int MAX_SDK_SUPPORTED_BY_ROBOLECTRIC = 18;
    
            public CustomAndroidManifest(FsFile androidManifestFile, FsFile resDirectory, FsFile assetsDirectory) {
                super(androidManifestFile, resDirectory, assetsDirectory);
            }
    
            @Override
            public int getTargetSdkVersion() {
                return MAX_SDK_SUPPORTED_BY_ROBOLECTRIC;
            }
        }
    }
    

    归功于此:https://github.com/robolectric/robolectric/issues/1025

    【讨论】:

      【解决方案4】:

      一些解决方案可能是:

      添加到测试中:
      @Config(emulateSdk = 18, reportSdk = 18)

      并使其类似于:

      @RunWith(RobolectricTestRunner.class)
      @Config(emulateSdk = 18, reportSdk = 18)
      public class YourClassTestNameTest {…
      

      【讨论】:

      • 对不起,伙计,我刚刚在您的代码中看到,您的崩溃与全屏活动有关,我已经看到了一些解决方法(可能有效),例如应用一些主题的参数或在测试中为此活动使用其他主题。抱歉目前在手机上。祝你好运!将堆栈跟踪中的一些部分添加到谷歌,如主题和应用程序紧凑,我想你会找到一些东西:)
      【解决方案5】:
      @RunWith(RobolectricGradleTestRunner.class)
      @Config(constants = BuildConfig.class, sdk = 21)
      

      解决了我的问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-10
        • 2015-01-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多