Robolectric Unit Test Sample Code for Android
In your project gradle file, change the classpath dependencies to the following.
[code language=”text”]
dependencies {
classpath ‘com.android.tools.build:gradle:1.2.3’
}
[/code]
In your app gradle file, add junit and roblectric dependencies. The android skd version should be 21 since Robolectric is not supporting newer versions of Android yet.
[code language=”text”]
dependencies {
compile fileTree(include: [‘*.jar’], dir: ‘libs’)
compile "com.android.support:appcompat-v7:21.0.+"
testCompile ‘junit:junit:4.12’
testCompile "org.robolectric:robolectric:3.0-rc3"
}
[/code]
Make sure junit works by create a basic junit test without the Adnroid framework. This file should be in app/src/test/java. You need to switch to project perspective in the directory navation widow in order to see this direction. All the Robolectric unit tests will be created in this folder going forward. To run this, make sure you select the Build Variants from the left sidebar and pick Unit Test, then right click the test file and select run.
[code language=”java”]
import org.junit.Test;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
public class JUnitTest {
@Test
public void checkJUnitWork() {
// We fail this unit test on purpose
assertThat(true, is(false));
}
}
[/code]
Before create Robolectric test Android tests, let’s create a custom Roobolectric Runner. This should be in the unit test folder.
[code language=”java”]
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.manifest.AndroidManifest;
import org.robolectric.res.FileFsFile;
import org.robolectric.res.FsFile;
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
public class CustomRobolectricRunner extends RobolectricTestRunner {
public CustomRobolectricRunner(Class<?> testClass)
throws InitializationError {
super(testClass);
String buildVariant = (BuildConfig.FLAVOR.isEmpty()
? "" : BuildConfig.FLAVOR+ "/") + BuildConfig.BUILD_TYPE;
String intermediatesPath = BuildConfig.class.getResource("")
.toString().replace("file:", "");
intermediatesPath = intermediatesPath
.substring(0, intermediatesPath.indexOf("/classes"));
System.setProperty("android.package",
BuildConfig.APPLICATION_ID);
System.setProperty("android.manifest",
intermediatesPath + "/manifests/full/"
+ buildVariant + "/AndroidManifest.xml");
System.setProperty("android.resources",
intermediatesPath + "/res/" + buildVariant);
System.setProperty("android.assets",
intermediatesPath + "/assets/" + buildVariant);
}
}
[/code]
Let’s test the activity title of the MainActivity class. Create the class RobolectricTestMainActivity and run it by right click the file and select run. This test will fail. To pass it, just change the string “Fail this test on purpose” to the correct title you have set for your activity.
[code language=”java”]
import android.app.Activity;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
@RunWith(CustomRobolectricRunner.class)
public class RobolectricTestMainActivity {
@Test
public void titleIsCorrect() throws Exception {
Activity activity = Robolectric.setupActivity(MainActivity.class);
assertThat("Should be Unit Test", activity.getTitle().toString(), equalTo("Fail this test on purpose"));
}
}
[/code]
At this point, everything should have set up for unit test using Robolectric. For more Robolectric unit test samples, keep on reading the following:
RobolectricTestTextView.java for testing TextView
[code language=”java”]
import android.app.Activity;
import android.widget.TextView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
@RunWith(CustomRobolectricRunner.class)
public class RobolectricTestTextView {
Activity activity;
@Before
public void init() {
activity = Robolectric.setupActivity(MainActivity.class);
}
@Test
public void failTest() {
TextView results = (TextView) activity.findViewById(R.id.hello);
String resultsText = results.getText().toString();
assertThat(resultsText, equalTo("Testing Android Rocks!"));
}
@Test
public void passTest() {
TextView results = (TextView) activity.findViewById(R.id.hello);
String resultsText = results.getText().toString();
assertThat(resultsText, equalTo("Hello World!"));
}
}
[/code]
RobolectricTestOptionMenu.java for testing the option menu item
[code language=”java”]
import android.app.Activity;
import android.view.Menu;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowToast;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
@RunWith(CustomRobolectricRunner.class)
public class RobolectricTestOptionMenu {
Activity activity;
@Before
public void init() {
activity = Robolectric.setupActivity(MainActivity.class);
}
@Test
public void onCreate_shouldInflateLayout() throws Exception {
final Menu menu = Shadows.shadowOf(activity).getOptionsMenu();
assertThat(menu.findItem(R.id.item1).getTitle().toString(), equalTo("item 1"));
assertThat(menu.findItem(R.id.item2).getTitle().toString(), equalTo("item 2"));
}
@Test
public void clickMenuItem_shouldDelegateClickToFragment() {
Shadows.shadowOf(activity).clickMenuItem(R.id.item4);
assertThat(ShadowToast.getTextOfLatestToast(), equalTo("Clicked Item 4"));
}
}
[/code]
RobolectricTestButton.java for testing button and button click.
[code language=”java”]
import android.app.Activity;
import android.content.Intent;
import android.widget.Button;
import android.widget.TextView;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.shadows.ShadowToast;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.*;
@RunWith(CustomRobolectricRunner.class)
public class RobolectricTestButton {
Activity activity;
@Before
public void init() {
activity = Robolectric.setupActivity(MainActivity.class);
}
@Test
public void clickingButton_shouldChangeResultsViewText() throws Exception {
Button button = (Button) activity.findViewById(R.id.button);
button.performClick();
Intent intent = Shadows.shadowOf(activity).peekNextStartedActivity();
assertEquals(SecondActivity.class.getCanonicalName(), intent.getComponent().getClassName());
}
@Test
public void testButtonClick() throws Exception {
Button view = (Button) activity.findViewById(R.id.button);
assertNotNull(view);
view.performClick();
assertThat(ShadowToast.getTextOfLatestToast(), equalTo("Hello"));
}
}
[/code]
RobolectricTestIntentService.java for testing intent service.
[code language=”java”]
import android.content.Context;
import android.content.Intent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.fakes.RoboSharedPreferences;
import static org.junit.Assert.assertNotSame;
@RunWith(CustomRobolectricRunner.class)
@Config(constants = BuildConfig.class)
public class RobolectricTestIntentService {
@Test
public void addsDataToSharedPreference(){
RoboSharedPreferences preferences = (RoboSharedPreferences) RuntimeEnvironment.application
.getSharedPreferences("example", Context.MODE_PRIVATE);
Intent intent = new Intent(RuntimeEnvironment.application,SampleIntentService.class);
SampleIntentService registrationService = new SampleIntentService();
registrationService.onHandleIntent(intent);
assertNotSame(preferences.getString("SAMPLE_DATA", ""), "");
}
}
[/code]
RobolectricTestAlarmManagerReceiver.java for testing AlarmManagerReceiver
[code language=”java”]
import android.app.Application;
import android.content.Intent;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.robolectric.Shadows.shadowOf;
@RunWith(CustomRobolectricRunner.class)
@Config(constants = BuildConfig.class)
public class RobolectricTestAlarmManagerReceiver {
@Test
public void startServiceForTheScheduledAlarm(){
Application application = RuntimeEnvironment.application;
Intent expectedService = new Intent(application, SampleIntentService.class);
AlarmManagerReceiver alarmManagerReceiver = new AlarmManagerReceiver();
alarmManagerReceiver.onReceive(application, new Intent());
Intent serviceIntent = shadowOf(application).getNextStartedService();
assertNotNull(serviceIntent);
assertEquals(serviceIntent.getComponent(),
expectedService.getComponent());
}
}
[/code]
To satisfy the above Robolectric unit test cases, create the following Android Application layout files and class files.
activity_main.xml in the res/layout/ folder
[code language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<TextView
android:id="@+id/hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="To Second Activity"
android:onClick="toSecondActivity"/>
</RelativeLayout>
[/code]
fragment_main.xml in the res/layout/ folder
[code language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="Fragment Main"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
[/code]
activity_main.xml in the res/menu/ folder, create the the menu folder if it’s not yet there.
[code language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:robolectric="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/item1"
android:title="item 1"
robolectric:showAsAction="ifRoom"/>
<item android:id="@+id/item2"
android:title="item 2"
robolectric:showAsAction="never"/>
</menu>
[/code]
fragment_main.xml in the res/menu/ folder.
[code language=”xml”]
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:robolectric="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/item3"
android:title="item 3"
robolectric:showAsAction="never"/>
<item android:id="@+id/item4"
android:title="item 4"
robolectric:showAsAction="never"/>
</menu>
[/code]
MainActivity.java
[code language=”java”]
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
Toast.makeText(this, "Clicked Item 1", Toast.LENGTH_SHORT).show();
return true;
case R.id.item2:
Toast.makeText(this, "Clicked Item 2", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void toSecondActivity(View v) {
Toast.makeText(this, "Hello", Toast.LENGTH_SHORT).show();
Intent i = new Intent(this, SecondActivity.class);
startActivity(i);
}
}
[/code]
SecondActivity.java
[code language=”java”]
import android.app.Activity;
import android.os.Bundle;
public class SecondActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
}
[/code]
MainFragment
[code language=”java”]
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
public class MainFragment extends Fragment {
public static Fragment newInstance() {
return new MainFragment();
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setHasOptionsMenu(true);
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle bundle) {
return inflater.inflate(R.layout.fragment_main, container, false);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.item3:
Toast.makeText(getActivity(), "Clicked Item 3", Toast.LENGTH_SHORT).show();
return true;
case R.id.item4:
Toast.makeText(getActivity(), "Clicked Item 4", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
[/code]
SampleIntentService.java
[code language=”java”]
import android.app.IntentService;
import android.content.Intent;
import android.content.Context;
import android.content.SharedPreferences;
public class SampleIntentService extends IntentService {
public SampleIntentService() {
super("SampleIntentService");
}
@Override
protected void onHandleIntent(Intent intent) {
SharedPreferences.Editor editor = getApplicationContext().getSharedPreferences(
"example", Context.MODE_PRIVATE).edit();
editor.putString("SAMPLE_DATA","sample data");
editor.apply();
}
}
[/code]
AlarmManagerReceiver.java
[code language=”java”]
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AlarmManagerReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent intentService = new Intent(context, SampleIntentService.class);
context.startService(intentService);
}
}
[/code]
Complete example in Github
References:
https://github.com/robolectric/robolectric-samples
http://nenick-android.blogspot.com/2015/03/android-studio-110-and-robolectric-30.html
Search within Codexpedia

Search the entire web
