Upgrade to Robolectric 4.x
Migrating to 4.15
Deprecations
Deprecated symbol
Replacement
org.robolectric:shadows-playservices
Use APIs provided by Google Player Services libraries
ActivityController#configurationChange(Configuration, DisplayMetrics, int)
ActivityController#configurationChange(Configuration, DisplayMetrics)
AttributeSetBuilder
Xml#asAttributeSet()
Config.Builder#setAssetDir()
See build system integration
Config.Builder#setLibraries()
See build system integration
Config.Builder#setPackageName()
See build system integration
Config.Builder#setResourceDir()
See build system integration
Robolectric#buildAttributeSet()
Robolectric#getAttributeSetFromXml()
Robolectric#flushBackgroundThreadScheduler()
ShadowLooper#runToEndOfTasks()
Robolectric#flushForegroundThreadScheduler()
ShadowLooper#runToEndOfTasks()
Robolectric#getBackgroundThreadScheduler()
This is only needed in the LEGACY
looper mode. We strongly encourage you to use the PAUSED
looper mode (which is the default)
Robolectric#getForegroundThreadScheduler()
This is only needed in the LEGACY
looper mode. We strongly encourage you to use the PAUSED
looper mode (which is the default)
RuntimeEnvironment#getMasterScheduler()
This is only needed in the LEGACY
looper mode. We strongly encourage you to use the PAUSED
looper mode (which is the default)
RuntimeEnvironment#setMasterScheduler()
This is only needed in the LEGACY
looper mode. We strongly encourage you to use the PAUSED
looper mode (which is the default)
ShadowApplication#runBackgroundTasks()
This is only needed in the LEGACY
looper mode. We strongly encourage you to use the PAUSED
looper mode (which is the default)
ShadowAssetInputStream#isNinePatch()
Only use this in LEGACY
graphics mode
ShadowRoleManager#addHeldRole()
ShadowRoleManager#addRoleHolder()
ShadowRoleManager#addAvailableRole()
ShadowRoleManager#addRoleHolder()
ShadowRoleManager#removeAvailableRole()
ShadowRoleManager#removeRoleHolder()
ShadowRoleManager#removeHeldRole()
ShadowRoleManager#removeRoleHolder()
Removals
Removed symbol
Replacement
org.robolectric:shadows-multidex
No longer needed with min SDK being 21+
AndroidManifest#supportsBinaryResourcesMode()
N/A (it always returned true
)
AndroidManifest#supportsLegacyResourcesMode()
N/A (it always returned false
)
ConfigMerger
Provider<Config>
DependencyResolver#getLocalArtifactUrls()
N/A (overriding getLocalArtifactUrl()
is enough)
Fs#fileFromPath(path)
Fs.fromUrl(path)
Fs#newFile(file)
file.toPath()
FsFile
Path
FsFile#getPath()
Fs.externalize(path)
FsFile#join(name)
path.resolve(name)
InvokeDynamicClassInstrumentor
ClassInstrumentor
IShadow#directlyOn(T, Class<T>)
Use a combination of Reflector
and Direct
MavenManifestFactory
See build system integration
PackageItemData#getClassName()
PackageItemData#getName()
ProxyMaker
Use a combination of Reflector
and Direct
Qualifiers#addScreenWidth()
Configuration#screenWidthDp
Qualifiers#addSmallestScreenWidth()
Configuration#smallestScreenWidthDp
Qualifiers#getOrientation()
Configuration#orientation
Qualifiers#getPlatformVersion()
Build.VERSION#SDK_INT
Qualifiers#getScreenWidth()
Configuration#screenWidthDp
Qualifiers#getSmallestScreenWidth()
Configuration#smallestScreenWidthDp
RoboSettings
Read/write the robolectric.scheduling.global
system property
Scheduler#idleConstantly()
Scheduler#setIdleState()
SdkPicker
DefaultSdkPicker
Shadow#directlyOn(T, Class<T>)
Use a combination of Reflector
and Direct
ShadowApplication#addWakeLock()
Use the PowerManager
APIs
ShadowApplication#clearWakeLocks()
ShadowPowerManager#clearWakeLocks()
ShadowApplication#getAppWidgetManager()
Context#getSystemService(Context.APPWIDGET_SERVICE)
ShadowApplication#getBluetoothAdapter()
BluetoothAdapter#getDefaultAdapter()
ShadowApplication#getForegroundThreadScheduler()
Use the PAUSED
looper mode (which is the default)
ShadowApplication#getInstance()
ApplicationProvider#getApplicationContext()
ShadowApplication#getLatestWakeLock()
ShadowPowerManager#getLatestWakeLock()
ShadowApplication#getSingleton()
N/A
ShadowAssetInputStream#getDelegate()
N/A
ShadowImpl#directlyOn(T, Class<T>)
Use a combination of Reflector
and Direct
ShadowMap#convertToShadowName()
N/A
Other Changes
TestLifecycle
no longer has a generic type.
Renamed ActivityData#isClearTaskOnLaungh()
into ActivityData#isClearTaskOnLaunch()
.
Renamed ResourceIds#makeIdentifer()
into ResourceIds#makeIdentifier()
.
Migrating to 4.14
Deprecations
Deprecated symbol
Replacement
org.robolectric:shadows-multidex
No longer needed with min SDK being 21+
Implements#looseSignatures()
Use either @ClassName
or @Implementation(methodName)
Supercedes
Supersedes
Removals
Migrating to 4.13
Breaking Changes
This release bumps the min SDK version from 19 to 21, following the move made by the AndroidX
ecosystem.
Deprecations
Deprecated symbol
Replacement
Scheduler
Use LooperMode.Mode.PAUSED
and ShadowLooper
's APIs
Removals
Removed symbol
Replacement
Qualifiers#addPlatformVersion()
N/A
RuntimeEnvironment#useLegacyResources()
N/A (it always returned false
)
Migrating to 4.12
Deprecations
Deprecated symbol
Replacement
RoboSettings#isUseGlobalScheduler()
LooperMode.Mode.PAUSED
RoboSettings#setUseGlobalScheduler()
LooperMode.Mode.PAUSED
Removals
Removed symbol
Replacement
RobolectricTestRunner#getConfig()
Provider<Config>
RuntimeEnvironment#setUseLegacyResources()
N/A
Migrating to 4.11
Breaking Changes
This release bumps the min SDK version from 16 to 19, following the move made by the AndroidX
ecosystem.
Deprecations
Deprecated symbol
Replacement
BackgroundTestRule
LooperMode.Mode.INSTRUMENTATION_TEST
Migrating to 4.10
Removals
Removed symbol
Replacement
Util#Util()
N/A
Migrating to 4.9
Deprecations
Deprecated symbol
Replacement
Util#intArrayToList()
N/A
Removals
Migrating to 4.0
Project Configuration
Robolectric 4.0 requires Android Gradle Plugin 3.2 or greater.
Update the configuration in your module's build.gradle
/build.gradle.kts
file:
Add the following in your gradle.properties
file:
android.enableUnitTestBinaryResources = true
If you have dependencies on com.android.support.test
, switch them to androidx.test
; see
Migrate to AndroidX .
Deprecations
The automatic migration tool includes a migration to help with this.
The following attributes of the @Config
annotation are no longer supported when
using binary resources mode:
assetDir
and resourceDir
: follow
the recommended file structure of your build system.
manifest
: Robolectric always uses the merged manifest generated by
the Android toolchain. If your test was using a custom manifest you'll need to adapt it to not
rely on that.
packageName
: to change your package name, override the
applicationId
in your build system.
Improper Use of Shadows
Prior to Robolectric 4.0, it was possible (but ill-advised) to get the shadow for an Android
framework object and invoke framework methods there. This could result in unexpected behavior (e.g.,
code in overridden methods in subclasses wouldn't be called). Shadow implementation methods are now
marked protected
to guard against this. Always invoke framework methods directly on the Android
class.
The automatic migration tool will fix most of these for you.
androidx.test
Robolectric 4.0 includes initial support for androidx.test
APIs . We strongly
recommend adding the latest version of androidx.test:core
as a test dependency and using those
APIs whenever possible rather than using Robolectric-specific APIs.
Troubleshooting
Robolectric 4.0 replaces its old home-grown resource handling code with a direct adaptation of
Android's resource handling code, using the full Android toolchain. This greatly improves fidelity
to the behavior of a real Android device, but if your tests were relying on the quirks of the old
code, you may need to fix your tests.
Some likely issues include:
android.view.InflateException: Binary XML file line #3: Failed to resolve attribute at index
17: TypedValue{t=0x2/d=0x7f01000e a=-1}
This happens when your Activity
is using a theme that lacks values
for certain attributes used by layouts. Make sure you've specified an appropriate theme for your
activities in your AndroidManifest
.