Simple way to test asynchronous actions in Android: Service, AsyncTask, Thread, RxJava etc.
Sometimes testing asynchronous actions might be very difficult but in most common cases during Android development it might be done with a very simple technique.
If you know basics of concurrency you can test asynchronous operations with a simple wait/notify.
The task:
There is a “Login Activity” with a simple login form and an asynchronous request to the server. Request is performed by IntentService in a background. Result is delivered with broadcast.
Create a test if login is working correctly.
This is a code of our LoginActivity:
- After pressing “Perform Login” button service starts and performs login in background. Response will be sent with a broadcast. The “action” of a result broadcast is also passed to the service.
- In the “LoginActivity” the broadcast receiver is registered to listen for the response from the service.
- When response is received the handleLoginResponse method is called.
Here is the relevant code:
To write a test we need to do a few things:
- Create LoginTestActivity that extends LoginActivity and override handleResponse method. When this method is called it means that response is received.
- No need to have this LoginTestActivity in production code that why we create a separate build flavor for testing.
- Define LoginTestActivity in AndroidManifest.xml of the separate flavor.
- Create the actual test.
LoginTestActivity is very simple:
This is how our project three looks like with a separate flavor:
And here is the actual test:
- It enters login and password into appropriate fields
- Presses “Perform login” button.
- Waits for asynchronous response with a simple wait/notify.
You should notice the important wait/notify calls.
Because Tests are running in a thread different from main we can easily call
synchronized(syncObject){
syncObject.wait();
}
When response from LoginService arrives, our LoginTestActivity calls onHandleResponseCalled and here we can notify the syncObject.
Note: we use the Service to perform asynchronous operation. This technique can be used with any asynchronous operation: AsyncTask, Thread, RxJava.