Espresso + mockito - Mock activity launch - android

I'm a beginner in android tests and what I would like to know is very simple.
I have a button which launch an activity on click and instead of launching the real activity I would like to replace it by the launch of another one.
How can I achieve that?
I'm using Espresso and mockito 2.0+. Thank you.

I doubt that this question still need an answer but in cas, just know that Dependency Injection like dagger will do the job. Inject your real activity on your app and another activity in your test by loading a different module.

Related

Android Jetpack Compose: should we do away with the MainApplication file?

I'm looking into slowly migrating an existing view-based Android app to a Jetpack Compose app. I figure I will take the opportunity to totally refactor the app, so I'm starting the Compose app from a blank slate, and trying to adopt the latest best practices as I go.
I've created a new project in Android Studio, using the "Empty Compose Activity" that's recommended in some of the docs I've read.
The project it creates lacks a MainApplication.kt file, and the manifest jumps straight into MainActivity, which defines only class MainActivity : ComponentActivity()
I note that the Android docs say "There is normally no need to subclass Application. In most situations, static singletons can provide the same functionality in a more modular way." which has me thinking that, as part of this refactor, I might try follow this implicit recommendation and see where it leads.
So my question is, is there anything that must be done in the Application class that would make me regret the structure that Android Studio has given me?
Does Koin dependency injection work fine outside of the main Application class? My app has services which have Room dependency injections I now do in Application class. All of that can be done elsewhere, presumibly in MainActivity?? (All Koin's examples use the Application class for DI!)
Can setting user permissions like location and file access can be done outside Application class??
I know I'm asking for an opinion here, but do you regard it as best practice to not subclass Application if you can avoid it, as the Android docs seem to suggest?
And lastly, is not subclassing the Application class (ie not having MainApplication.kt) somehow related to the new Compose way of building apps?
thanks!
John
The skeleton code that you get from creating a Compose project from Android Studio does not subclass Application because it just gives you the bare essentials to have a functional compose app.
The Application class is still the right place to initialize your dependency injection graph, plus other libraries that need a one-off initialization, like for instance Timber.
Requesting runtime permissions should be done locally, at the time you need those. If you need some permission to start your application from the get go, ask for those in your activity, the Application is not the right place for that.

Android Robotium Test for Non activity class

Can anyone tell me how can I write Robotium tests for non activity classes?
I have seen lot of example for activity classes but not for non activity classes.
Is it possible?
Thank You.
Robotium is mostly useful for interacting with your app in a test case. These interactions are usually with activities.
If you want to test other classes, there's no need to use Robotium. You might look into Robolectric for running tests in the JVM on your computer.

Mocking android applications like the contacts app using Mockito

I am trying to write functional tests for an android application. The problem is that most functional testing frameworks that I have explored (calabash-android, robotium) have a limitation on the number of activities from different applications that can be tested in the same test. So if in one workflow I need to select some contacts from the android contact picker I cant test that entire flow because the contact picker activity is part of the android contacts application and the framework can't test an activity from my application and the contacts application at the same time.
One possible solution my team thought of was to mock out the call to the contacts activity to return a dummy intent with contact information so that our application workflow can be tested. We are trying to use mockito to achieve this. However I am stuck pretty early on. Here is what I am trying to do
MyActivity mockActivity = mock(MyActivity.class);
when(mockActivity.startActivityForResult(<?>,anyInt())).thenReturn(fakeIntent);
I am not sure what to put in the first parameter in the second line. I have tried Intent.class and android.content.Intent.class however it throws a compile error. If anyone has worked with mocking activities using mockito, some help will be greatly appreciated.
P.S. - If I understand correctly mocking is used more in unit testing than functional testing. So these tests would be more of a hybrid. If anyone has a better suggestion on how to go about these functional tests on android I am all ears.
It's hard to answer this without knowing the signature of your startActivityForResult method, but the general idea is to use any(Xxx.class), where Xxx is the type of the parameter. So either
when(mockActivity.startActivityForResult(any(Xxx.class),anyInt())).thenReturn(fakeIntent);
or the (kind of equivalent)
doReturn(fakeIntent).when(mockActivity).startActivityForResult(any(Xxx.class),anyInt());
The issue is that you cannot really "mock" (actually "spy") on the activity you're testing since it is created out of your control by Android's instrumentation code. In a unit-test environment where you would have control, you could follow the mock(MyActivity.class) or spy(myActivityInstance) path (spy would actually be better because you could re-use most of the activity's original implementation), but here not.
The only solution I found for this dilemma was to move certain functionality out of the activity into utility classes, ideally utilizing roboguice for that (#ContextSingletons can be used to process activity results). Then, in your test project, you would create your own test guice injector, set that as base application injector before you call getActivity() for the first time and then let the activity work on your mocked utility class.
I outlined the complete process here.

Android: jUnit Test Android Library

I am trying to test a library developed by me through jUnit, but I'm having some problems. This library requires an activity to be instantiated. However, following the tutorial (http://www.vogella.com/articles/JUnit/article.html), I can not instantiate the object because I dont have the activity. You can create a dummy activity?
Thanks :)
To test an Activity you should normally use ActivityInstrumentationTestCase2. When you invoke getActivity() the Activity under test will be created.
If you are testing a library project, the post android: testing library project would be also of help.
Unit testing Android applications is tricky because of the stubbed out API implementation ("java.lang.RuntimeException: Stub!")
If you want to unit test your Android Activities and such, Robolectric is a nice option: http://pivotal.github.com/robolectric/

How to create Mock objects for Android Activities (Junit)

I am fairly new to unit testing, in android specifically. I have written an application with numerous activities. However, some of these activities rely on certain objects for them to populate the activity's views. I guess my question is: Is there a way I can mock up the objects within the Activity and make the activity use that created mock object from my Junit tests? Thanks in advance, I cant find the solution for this anywhere?
You can also take a look at AndroidMock:
http://code.google.com/p/android-mock/wiki/UsingAndroidMock
It is a Mock Objects framework for Android build on top of EasyMock.
If you refere to the developer guide under Create a Local Unit Test Class heading, you will find the answer to your question. Also refer to the "Mock Android Dependecies" sub heading on the same page.

Categories

Resources