簡體   English   中英

使用Robolectric運行的Android Lollipop Appcompat問題

[英]Android Lollipop Appcompat problems running with Robolectric

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

注意 :截至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 注釋中的鏈接提供了更多信息

在與清單相同的hierarki級別添加project.properties文件,其中包含以下內容:

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

確保appcompat版本與gradle文件中的版本相同。

使用這個自定義RobolectricTestRunner解決了我遇到的類似問題。 這也意味着您在每次測試中都不需要@Config(emulateSdk = 18)。

替換:@RunWith(RobolectricTestRunner.class)

在所有Robolectric測試中使用:@RunWith(MyRobolectricTestRunner.class)

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

一些解決方案可能是:

加入測試:
@Config(emulateSdk = 18,reportSdk = 18)

並使它像:

@RunWith(RobolectricTestRunner.class)
@Config(emulateSdk = 18, reportSdk = 18)
public class YourClassTestNameTest {…
@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)

解決了我的問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM