Robolectric Unit Test Sample Code for Android
In your project gradle file, change the classpath dependencies to the following.
dependencies { classpath 'com.android.tools.build:gradle:1.2.3' }
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.
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" }
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.
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)); } }
Before create Robolectric test Android tests, let’s create a custom Roobolectric Runner. This should be in the unit test folder.
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); } }
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.
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")); } }
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
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!")); } }
RobolectricTestOptionMenu.java for testing the option menu item
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")); } }
RobolectricTestButton.java for testing button and button click.
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")); } }
RobolectricTestIntentService.java for testing intent service.
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", ""), ""); } }
RobolectricTestAlarmManagerReceiver.java for testing AlarmManagerReceiver
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()); } }
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
<?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>
fragment_main.xml in the res/layout/ folder
<?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>
activity_main.xml in the res/menu/ folder, create the the menu folder if it’s not yet there.
<?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>
fragment_main.xml in the res/menu/ folder.
<?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>
MainActivity.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); } }
SecondActivity.java
import android.app.Activity; import android.os.Bundle; public class SecondActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } }
MainFragment
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); } } }
SampleIntentService.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(); } }
AlarmManagerReceiver.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); } }
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