Mocking API responses for Android Test - android

I want to mock the API responses for my Android Async Network Tasks for Unit Testing. Anyone can tell me how to do this? I'm beginner to testing in Android.

Create your own class implementing the same API as your 'real' networking class. When one of its methods, say, method requestData() gets called, wait a bit inside the method then return some mock data in the same way as the real class is supposed to do.

Related

Android MVP testing methods that needs network operations

I'm testing my app using Junit and Mackito, testing methods is gone good so far but not with methods that need network operations, how to test them properly, so that the assert is called after fetching data from the backend?
In general you should test your app, not server side logic. So just mock methods which do network calls.
But, if you want to test network layer of app itself, there is good way, which I recommend, to do that - WireMock
Simply saying it creates locally running webserver which response with predefined responses.
Is not a good idea test methods that depend on network calls.
Better test backend apart and mock it in client.
Anyways, if you want to wait for the data use: Thread.sleep(Xms) in test method after network call and before your asserts.
#Test
public void testcase() throws InterruptedException {
// make actions and network call
// Wait, for example 2 seconds. It depends a lot of connection
Thread.sleep(2000);
// Then assert whatever you want
}

Android Unit test API calls with Retrofit2

I haven't done any testing in Android, so please bear with me if this seems a stupid question.
I'm developing an app which makes a lot of network calls from a restful API service. To make the network calls, I'm using Retrofit2 and RxJava.
What would be the best practice/framework to just test if these calls are working? I've started to read the Google Codelab for testing which uses Junit4 and Mockito, but I don't want to do any clicking in the UI to start a test currently, just checking for different API versions which calls are supported or not.
Here some steps for you that I am using:
Use mockito & junit4, for sure :)
I avoid UI tests for these cases
Pass your retrofit Api as a parameter to a class that you want to test
In the test create a mock retrofit api, pass this one as a parameter so you can choose what you want your "Api" to return e.g. objects or errors (see Mockito.when())
Use RxJava's TestSubscriber to test a method e.g. Observable<Location> getLocationFromApi()
Avoid threading in your testing class (e.g. like .observeOn(mainThread())). If inevitable use awaitTerminalEvents in TestSubscriber. If there is no terminal even rethink your test
General tips:
Try to modularize your code so each class has few functionality -> easier to test.
Be patient and don't expect to write tests for e.g. 5% of your code in just one week :) It's a slow process regardless team size

Functional tests in android. How to wait for fragment result?

I'm trying to add test to a quite big android project. So, I'm able to add the test, both to activity both to fragments, and get they run correctly.
But in my case, most of the fragments, when started, starts a Runnable into a new Thread. This thread connect to APIs, request and parse data, and return them to a handler, in the calling fragment.
The question is: How am I supposed to ask the test to wait until the data are retrieved by handler, so I can check them values?
How about instead of waiting for the values to return from real objects. You create mock objects that can return whatever value want instantly. Mockito is a great mocking framework that is very easy to use on Android.
http://code.google.com/p/mockito/
The way you go about using it is to create mock objects as opposed to real objects and you have to find "seams" to insert them into your tests. With a mock object, you can get it to return whatever value you want for any of its methods. With a mock object you can isolate dependencies. Therefore, in your example, you may want to create mock objects that mock the object that is connecting to the api because then you can return whatever value your tests need for the server to return to test whichever part of your app that you are testing. For example, if your testing whether the signUp activity is opened if the server returns that the user has entered a wrong password, you create a mock object that will return false to your activity and then insert that into where the real object is supposed to be.
Most people have issues testing existing code (that was not built with testability in mind) because there usually aren't any seams to insert test objects. Check out this awesome blog about how to make code more testable. It is contains really great advice.
http://googletesting.blogspot.com/2008/08/by-miko-hevery-so-you-decided-to.html

Using excessive amount of network calls in android

I am developing an android application that needs to communicate a lot with a remote server. For this task I wrote a class that handles all the network communication.
Do I need to make for every single method as an Asynctask? What about methods that I am dependent on for the rest of the code execution? (thus needs to be done synchronously - like waiting for an answer on registration?)
I am asking this because I already had a small app before to communicate with a remote server and I didn't use any Asynctasks, this one crashes on every method being called though.
Edit -
Meanwhile - before making a class of my own I found a great tutorial related to a google libraray that already handle that the libraray name is Volley the tutorial I looked on is this one
Yes, every network call has to asynchronous. You don't need to make every single method in you class async, but i would refactor the code in a way that only one peace of code actually does the calls and this peace has to be async. If you have following code that depends on the response from the server, then use a callback.
In pseudo code that would look something like this:
void makeNetworkCall(command, listener){
async(){
result = command.execute();
listener.onCommandSuccess(result);
}
}
Do I need to make for every single method as an Asynctask?
Yes. Android requires networking code to be executed asynchronously, so the user interface never gets blocked.
What about methods that I am dependent on for the rest of the code execution?
You can wait for an Asynchtask to finish execution. Refer to this question.

Testing Strategy for Web Services based Android app

I have a web services based app i.e. each activity calls a particular web service and populate data into view. I haven't done any testing yet but I was in the process of switching to Volley and thought I might add some testing too.
I was wondering what testing strategies should be for such apps. I'm playing around with the gradle-android-test-plugin and although Robolectric doesn't play well with Volley yet, it should soon (I hope).
Anyways, so the structure I use for my app is this:
ObjectJacksonRequest class which get the data from the webservices and parses them into POJOs
RequestQueue standard volley request queue
BaseActivity the parent activity of all my app's activities which houses the RequestQueue object and other common stuff
Various Abstract activities which I use to separate the UI code from the network code. For example, the AbstractAppleActivity is extended by any activity that needs an apple. The abstract activity does things like check if the Apple is still in memory when returning, load new ones, set up adapters for list views, etc.
Here's the questions I currently have. I have some intuition on the answers should be but I'd like to hear from the community. I'm sure there are others questions too that people might have and we can add those to this list:
What's a good way to test the ObjectJacksonRequest object for the various web services ? Should I be writing a separate test for each web service that returns and object ?
Should I be testing network requests with the actual webservices or mock the responses ?
Should I be testing the BaseActivity and the abstract activities or the activities that extend it for it's functionality ?
What is the best way to test an activity that doesn't have any values inserted until the web request is completed ? For example, an activity that loads a list of apples.
What's a good way to test the ObjectJacksonRequest object for the various web services ? Should I be writing a separate test for each
web service that returns and object ?
If I am understanding it correctly you want to test the webservice backend. In that case I would write a test per call, or even multiple tests per call one testing each response senario.
Should I be testing network requests with the actual webservices or mock the responses ?
I would mock out the responses. It is my experience that if you test against a real webservice, you will get random fails because the connection was to slow or timed out or something and you end up running your test twice just to be sure it wasn't a random fail.
Should I be testing the BaseActivity and the abstract activities or the activities that extend it for it's functionality ?
I would not test the BaseActivities unless they have a lot of logic.
What is the best way to test an activity that doesn't have any values inserted until the web request is completed ? For example, an
activity that loads a list of apples.
Mock out the webservice response, so that it has values. You can do this with Robolectric. I believe the relevant method is Robolectric.addRequestInterceptor
I have more experience with testing now so here are my suggestions gathered for various sources:
- What's a good way to test the ObjectJacksonRequest object for the various web services ?
- Should I be writing a separate test for each web service that returns an object ?
- Should I be testing the BaseActivity and the abstract activities or the activities that extend it for it's functionality ?
All of these questions can be bundled into one. This is the question of testing inheritance hierarchies. The answer is, unfortunately, it depends. In most cases however, for abstract classes, testing the sub-classes will test the parent classes as well. Unless you have methods that have different use cases in different sub-classes, in that case you might want to test the abstract class so you can test all the cases as you code them (although if this is happening, you might be better off defining more objects).
- Should I be testing network requests with the actual webservices or mock the responses ?
This is an easy one. Always mock. As the other answer mentioned, you run the risk of writing flaky tests if you are using real webservices. Not to mention that testing the webservices is not your responsibility. You should only be testing code that you are responsible for.
- What is the best way to test an activity that doesn't have any values inserted until the web request is completed ? For example, an activity that loads a list of apples
This should follow from the mocked service. Once you have the mocked service. You can use it to send data to the activity in a reliable way and test the outcome.
Other Notes:
While the above are specific answers. In general I've found it useful to make some engineering decisions that facilitate not only testing but modularity of your apps. So these are some of my tips and to-donts from the engineering mistakes I had in my app design as per the question.
Use custom wrappers for services: In my question I am trying to move from Android's original HTTP to Volley. Part of the reason for these issues is that the app design couples the app with the networking library. One way to get around this is to use wrapper classes that are injected into your code. The underlying implementation of the wrapper class can then change without affecting the other source code. I have a blog post on this topic here.
Use Java modules: The Android gradle plugin in based on the gradle java plugin. You can therefore create Java library modules in your Android app project. I have found this is the best way to unit test your code that doesn't interact with Android API's. This is way easier and faster than both the Android test framework and Robolectric. I find that when I'm using a Java library module, my UI code becomes lighter because I'm trying to have as much work done in the Java module as possible.

Categories

Resources