2

I got an Android app that requires authentication to be used. As the project grows up, I want to add unit testing in my app.

To do that, I use Espresso 2.1

The thing is:

  1. My LoginActivity is called by startActivityForResult
  2. It shows the form
  3. a. If the credentials are wrong, it stays on the LoginActivity
  4. b. If the credentials are ok, it finish with a RESULT_OK.

So in my espresso test class, I have some unit tests. Everything is fine with the not ok cases, the problem is on the ok case.

I need to check that the result is RESULT_OK but as the Activity finishes, espresso failed with a

android.support.test.espresso.NoActivityResumedException: No activities in stage RESUMED. Did you forget to launch the activity. (test.getActivity() or similar)?

Here is my questions:

  • Is there a way to test the setResult of the Activity ?
  • Is there a workaround (I'd like to not use any of them, but at least...) to be able to test that ?

I've read things about Espresso-Intents but I can't figure out an example on how I can start an activity of my own package and check the result is a RESULT_OK.

halfer
  • 19,824
  • 17
  • 99
  • 186
Quentin Klein
  • 1,263
  • 10
  • 27
  • http://stackoverflow.com/a/29923942/1368705 yes, it is possible to setData (any result you wish), just like I show in that answer I will give it a closer look by tomorrow. – appoll May 18 '15 at 17:20
  • For those who have same issue, I just found a solution to my similar problem. http://stackoverflow.com/a/35214915/513413 – Hesam Feb 05 '16 at 01:45

2 Answers2

2

Very short answer:

  • yes, it is possible to set the result by doing

    Intent resultData = new Intent();
    resultData.setData(...);
    Instrumentation.ActivityResult result = new Instrumentation.ActivityResult(Activity.RESULT_OK, resultData);
    intending(toPackage("package.containing.login.activity")).respondWith(result);
    

You would asses that the RESULT_OK was received by checking that one of the views contains the desired returned information. If that is not clear enough, post any questions in the comments and will try to help.

how I can start an activity of my own package

How would the user do it? Probably by clicking on a button or any other view interaction, right?

appoll
  • 2,910
  • 28
  • 40
  • Ok I think I get the idea but: the instrumentation class extends `ActivityInstrumentationTestCase2` so I'm already on it. In fact it is espresso that starts the LoginActivity for me. So I think I could do something like: `intending(toPackage("package#LoginActivity")).respondWith(result);`. I'll try this asap and I get back, anyway thanks for the answer **EDIT**: This won't work as I cant edit fields between `intending` and `respondWith` – Quentin Klein May 18 '15 at 17:36
  • Be aware that with Espresso 2.1 the ActivityInstrumentationTestCase2 is deprecated and you should use ActivityTestRule instead. In your specific case IntentTestRule. – appoll May 18 '15 at 19:03
  • the respondWith is only being called once you send the intent (with the result, the one you created) back to the initial activity. step by step, you would: 1. create the intent with the result. 2. fill in the form. 3. trigger the intent to be sent back (login button) – appoll May 18 '15 at 19:38
  • I think I get it, but not sure, In fact `intending` is "mocking" the result. I mean, it will act like the login worked ? So it won't check if the login worked, but it will fake a correct login but returning `RESULT_OK` – Quentin Klein May 19 '15 at 07:26
  • Something like that, yes. So you would have two different tests for successful / unsuccessful login. I will try to reproduce something similar asap and be back with an update. – appoll May 19 '15 at 07:54
-2

Do you really need Espresso for this test? Robolectric ActivityShadow has getResultCode() and getResultIntent() methods.

final Intent startIntent = new Intent();
final ResultActivity activity = Robolectric.buildActivity(ResultActivity.class)
    .withIntent(startIntent)
    .create()
    .get();

final String data = "data";
activity.onEventMainThread(new CompletedEvent(data));

assertEquals(RESULT_OK, shadowOf(activity).getResultCode());

final Intent resultIntent = shadowOf(activity).getResultIntent();
assertEquals(data, resultIntent.getStringExtra(DATA_KEY));

ResultActivity sets result and finishes after receiving a CompletedEvent. In this test the event handler is called directly to simulate the event.

anagaf
  • 2,120
  • 1
  • 18
  • 15