Issue
I'm trying to write a test to verify intent launching with espresso, the problem is that intended() does not record any intent.
I have this test
@Test
public void shoulddosomething(){
startActivity();
intended(hasComponent(hasClassName(TemplatePictureCaptureActivity.class.getName())));
}
and in my activity i have this code
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(onRequestLayout());
Intent intent = new Intent(this, TemplatePictureCaptureActivity.class);
startActivity(intent);
}
The test result is this.
android.support.test.espresso.base.DefaultFailureHandler$AssertionFailedWithCauseError: Wanted to match 1 intents. Actually matched 0 intents.
IntentMatcher: has component: has component with: class name: is "cat.helm.recertel.ui.templatepicturecapture.TemplatePictureCaptureActivity" package name: an instance of java.lang.String short class name: an instance of java.lang.String
Matched intents:[]
Recorded intents:[]
I have tried to launch the intent inside onClickListen and it worked, but without it i can't get it to work. I also tried with idling resources with no luck. Do you know how to achieve this?
Solution
This might be related to a race condition on the Intents component initialization and not with a race condition between the startActivity
call and the usage of intended
. If you start your activity from the SUT activity onCreate
or onResume
methods you should take a look at the following test rule.
I've created an IntentsTestRule fixing this issue. https://gist.github.com/pedrovgs/6a305ba4c5e3acfac854ce4c36558d9b
package com.aplazame.utils
import android.app.Activity
import androidx.test.espresso.intent.Intents
import androidx.test.rule.ActivityTestRule
class ExhaustiveIntentsTestRule<T : Activity> : ActivityTestRule<T> {
private var isInitialized: Boolean = false
constructor(activityClass: Class<T>) : super(activityClass)
constructor(activityClass: Class<T>, initialTouchMode: Boolean) : super(activityClass, initialTouchMode)
constructor(activityClass: Class<T>, initialTouchMode: Boolean, launchActivity: Boolean) : super(
activityClass,
initialTouchMode,
launchActivity
)
override fun beforeActivityLaunched() {
super.beforeActivityLaunched()
Intents.init()
isInitialized = true
}
override fun afterActivityFinished() {
super.afterActivityFinished()
if (isInitialized) {
// Otherwise will throw a NPE if Intents.init() wasn't called.
Intents.release()
isInitialized = false
}
}
}
The main difference with the original IntentsTestRule implemented in AndroidX is the Intents.init() initialization. This time is invoked before starting the SUT activity. Keep in mind that this test rule will also record the intent used to start the SUT activity.
Answered By - Pedro Vicente Gómez Sánchez
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.