Robolectric配置过程

配置build.gradle

testCompile "org.robolectric:robolectric:3.1.4"

配置Robolectric

在需要执行的测试类上,需要对Robolectric进行配置。可以把所有配置放到基类里面,其他测试类通过继承的方式来共享配置

/**
* TestCase的基类,主要对使用到的Robolectric进行配置。
* 

* manifest:使用主代码的manifest
* packageName:如果build.gradle中配置了applicationId,此处需要制定包名
* constants:配置常量
* sdk:Robolectric目前不支持24,所以配置为23 *

* Created by snow * Date: 2016/12/2 * Time: 下午2:14 */ @RunWith(RobolectricTestRunner.class) @Config(manifest = "src/main/AndroidManifest.xml", packageName = "com.snow.demo", constants = BuildConfig.class, sdk = 23) public class BaseTestCase { }

支持MultiDex

Robolectrix对MultiDex支持不是很好,在执行Application.attachBaseContext()方法时,可能会抛出异常,因此需要进行捕获处理

@Override
protected void attachBaseContext(Context base) {
    /**
        * Robolectric 对MultiDex的支持有问题,参考issue
        */
    try {
        super.attachBaseContext(base);
    } catch (Exception multiDexException) {
        // Work around Robolectric causing multi dex installation to fail, see
        // https://code.google.com/p/android/issues/detail?id=82007.
        boolean isUnderUnitTest;

        try {
            Class robolectric = Class.forName("org.robolectric.Robolectric");
            isUnderUnitTest = (robolectric != null);
        } catch (ClassNotFoundException e) {
            isUnderUnitTest = false;
        }

        if (!isUnderUnitTest) {
            // Re-throw if this does not seem to be triggered by Robolectric.
            throw multiDexException;
        }
    }
}

NoClassDefFoundError: javax/microedition/khronos/opengles/GL

在运行测试用例时,有可能会报上述异常,解决方法是在build.gradle中添加如下依赖:

testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1'

Robolectric中的Shadow概念

作用

模拟了Android系统中的真实对象,并对其中的一些方法做了hack。

名字

What's in a Name?
Why "Shadow?" Shadow objects are not quite Proxies, not quite Fakes, not quite Mocks or Stubs. Shadows are sometimes hidden, sometimes seen, and can lead you to the real object. At least we didn't call them "sheep", which we were considering.

code

Rocolectric的Shadows类中提供了很多的重载方法,提供所需的Shadow对象。

public static ShadowActivity shadowOf(Activity actual) {
    return (ShadowActivity) ShadowExtractor.extract(actual);
}

public static ShadowActivityGroup shadowOf(ActivityGroup actual) {
    return (ShadowActivityGroup) ShadowExtractor.extract(actual);
}

public static ShadowActivityManager shadowOf(ActivityManager actual) {
    return (ShadowActivityManager) ShadowExtractor.extract(actual);
}

public static  ShadowAdapterView shadowOf(AdapterView actual) {
    return (ShadowAdapterView) ShadowExtractor.extract(actual);
}

public static ShadowAlarmManager shadowOf(AlarmManager actual) {
    return (ShadowAlarmManager) ShadowExtractor.extract(actual);
}

public static ShadowAlertDialog shadowOf(AlertDialog actual) {
    return (ShadowAlertDialog) ShadowExtractor.extract(actual);
}

ShadowIntent:

/**
* Shadow for {@link android.content.Intent}.
*/
@SuppressWarnings({"UnusedDeclaration"})
@Implements(Intent.class)
public class ShadowIntent {
  @RealObject private Intent realIntent;

  /**
   * Non-Android accessor that returns the {@code Class} object set by
   * {@link Intent#setClass(android.content.Context, Class)}
   *
   * @return the {@code Class} object set by
   *         {@link Intent#setClass(android.content.Context, Class)}
   */
  public Class getIntentClass() {
    try {
      return Class.forName(realIntent.getComponent().getClassName());
    } catch (ClassNotFoundException e) {
      throw new RuntimeException(e);
    }
  }
}

你可能感兴趣的:(Robolectric配置过程)