Espresso intent test failing

14,790

Solution 1

I had the same problem and solved it by using IntentsTestRule instead of ActivityTestRule. IntentsTestRule is a subclass of ActivityTestRule. Set up your @Rule which creates the activity like so:

@Rule
public IntentsTestRule<MyActivity> mActivity = new IntentsTestRule<MyActivity>(MyActivity.class) {
    @Override
    protected Intent getActivityIntent() {
        ...
    }
};

See the following project for more information: https://github.com/googlesamples/android-testing/tree/master/ui/espresso/IntentsBasicSample

Solution 2

If you are using a custom ActivityTestRule, you can add the proper Intents.init(), Intents.release() calls:

@Override
protected void afterActivityLaunched() {
    Intents.init();
    super.afterActivityLaunched();
}

@Override
protected void afterActivityFinished() {
    super.afterActivityFinished();
    Intents.release();
}

Solution 3

I had the same problem, however, switching to IntentsTestRule did not work, too. So I switch back to ActivityTestRule and called Intents.init() before and Intents.release() after the test which sent the Intent.

For more information please see this reference.

Solution 4

Instead of using IntentsTestRule which is now @deprecated in java, you should use the recommended activityScenarioRule like so:

@RunWith(AndroidJUnit4::class)
@MediumTest
class YourActivityTest {

    @get:Rule
        val activityScenario = activityScenarioRule<YourActivity>()

    @Before
        fun setUp() {
            launchActivity<YourActivity>()
            Intents.init()
        }
    
        @After
        fun tearDown() {
            Intents.release()
        }

    @Test
        fun should_goBackTo_MainActivity_onBackButton_click() {

            onView(withId(R.id.goBackBtn)).perform(click())
            intended(hasComponent(hasShortClassName(".MainActivity")))
        }
}

Don't forget adding this in your build.gradle file:

android {
defaultConfig {
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
testOptions {
unitTests {
includeAndroidResources = true
}
}
// testing
androidTestImplementation 'androidx.test:core:1.3.1-alpha02'
androidTestImplementation 'androidx.test:core-ktx:'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'   
//for the activityScenarioRule syntax to work in kotlin,
//We add the ktx version of androidx.test.ext:junit
androidTestImplementation 'androidx.test.ext:junit-ktx:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-contrib:3.3.0'
androidTestImplementation 'androidx.test.espresso:espresso-intents:3.3.0'
androidTestImplementation 'androidx.test:runner:1.3.0'
androidTestImplementation 'androidx.test:rules:1.3.0'
}
Share:
14,790
HirenPatel_
Author by

HirenPatel_

Updated on June 07, 2022

Comments

  • HirenPatel_
    HirenPatel_ about 2 years

    I'm learning android instrumentation testing with espresso. I have an app which has a drawer menu and there is a menu called About. I was testing click on that menu item and contents of activity.

    testfunction:

      @Test
    public void testNavigationDrawerAboutMenu() {
        onView(withId(R.id.drawer_layout))
                .perform(DrawerActions.open()); //open drawer
        onView(withText("About")).perform(click());
        onView(withId(R.id.aboutsptemail)).check(matches(withText(R.string.screen_about_support_email)));
        onView(withId(R.id.aboutcpright)).check(matches(isDisplayed()));
        onView(withId(R.id.aboutprivacy)).check(matches(isDisplayed()));
        onView(withId(R.id.abouttermsconditions)).check(matches(isDisplayed()));
        onView(withId(R.id.aboutsptemail)).perform(click());
    }
    

    now the last textview has weblink embedded in it. so when you click on it, it opens the link(www.support.com) in a web view within the app. I want to test this functionality. so I tried this:

    intended(hasComponent(WebViewActivity.class.getName())); //check if webview called on supportEmail link click
    

    but test fails with this error trace:

    java.lang.NullPointerException: Attempt to invoke virtual method 'android.support.test.espresso.intent.OngoingStubbing android.support.test.espresso.intent.Intents.internalIntending(org.hamcrest.Matcher)' on a null object reference
    at android.support.test.espresso.intent.Intents.intending(Intents.java:155)
    at com.ScanBuy.SmartLabel.NavigationDrawerActivityTests.testNavigationDrawerAboutMenu(NavigationDrawerActivityTests.java:94)
    at java.lang.reflect.Method.invoke(Native Method)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55)
    at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:270)
    at org.junit.rules.RunRules.evaluate(RunRules.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:59)
    at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:262)
    at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1879)
    

    I have also tried resolve by idling the resources before checking for intent. But didn't work. Can anybody help?

  • HirenPatel_
    HirenPatel_ about 8 years
    ya. Perfect. Thanks.
  • IgorGanapolsky
    IgorGanapolsky almost 7 years
    Is this preferable to using IntentsTestRule?
  • bonnyz
    bonnyz almost 7 years
    It's actually the same thing. If you already have a custom ActivityTestRule or you want to enable this feature dinamically it makes sense to use this approach, otherwise just use the IntentsTestRule.
  • Dhruvam Gupta
    Dhruvam Gupta over 6 years
    Declaring this rule calls init() and release() internally but If you don't want to declare IntentsTestRule then you will have to call Intents.init() explicitly in your code which will make your code run without any error.
  • Ionut Negru
    Ionut Negru about 3 years
    You don't need to manually launch your activity if you are using ActivityScenarioRule.