Testing in Android with mock UI components

As described in an earlier post, Android is not friendly to mocking frameworks or mock-style testing.  If you want to test any class in your application that deals with the Android API, it’s best to run your tests through the emulator, accessing real Android classes.  It’s unfortunate because you’re not just testing your application.  You’re also testing Android.  Anyway, here’s a way to mock a UI component.

If you’re just starting, here are a couple notes to keep you on the right track.

  • Android is bundled with JUnit 3.  Don’t try using an updated JUnit library or another testing framework.  The Android jar doesn’t contain any functional code, so all test cases have to be run in the emulator, which uses JUnit 3.  The test framework that will work best is in the Android API.
  • If you need basic implementations of Android classes, try to avoid mocking them.

“Mock”ing

In my latest test, I needed a TextView so that I could call the simplest method, setText(String).  I’ll describe how I got one.

Don’t bother with the android.test.mock package.  It just contains implementations of classes that throw UnsupportedOperationExceptions.  There isn’t anything there that I have yet found useful.

  1. In the test case, instead of extending TestCase, extend at InstrumentationTestCase or, if necessary, one of its subclasses.  It’ll set up most of the stuff that’s available in an Activity and make it available to your test case.
    public class AnAndroidTest extends InstrumentationTestCase {
  2. Create a mock implementation of TextView or the class you need.
    public class MockTextView extends TextView {
      public MockTextView(final Context context) {
        super(context);
      }
    }
  3. The TextView constructor needs a real Context object because it will call methods on it.  The context is difficult to mock because parts of it are private to Android.  Since the Android JAR is just an API and doesn’t have any functional code, you couldn’t even see the methods if you tried.  They only exist in the VM in the emulator.  AFAIK, if you can’t see a method, you can’t mock it.  That’s why your test case extends InstrumentationTestCase.  Put this in it.
    final TextView textView = new MockTextView(this.getInstrumentation().getContext());

Now write the test case.  The text view is real and has a fully functional context, so the emulator will have everything it needs to support your test case.

Posted in Android at June 1st, 2009. 1 Comment.

Android application Green Mileage open sourced

Green Mileage is now an open source application at Google Code.  You can find the full source for most of the Android posts on this site in it at http://code.google.com/p/greenmileage/.  Just click the Source tab, then the Browse link.

The code needs a lot of cleanup, but is still probably worth a look if you’re new to Android.

Posted in Android at April 27th, 2009. 4 Comments.

Android application icon tutorial

Assigning an icon to your Android application just takes a minute.  Actually creating the icon may take a bit longer. 😛

  1. Create a 48×48 PNG and drop it into /res/drawable.  The name of this file is usually “icon.png”.
  2. Open your AndroidManifest.xml.
  3. Right under the root “manifest” node of the XML, you should see the “application” node.  Add this attribute to “application”. (The “icon” in “@drawable/icon” refers to the file name of the icon.)
    android:icon="@drawable/icon"

Your app is now iconned.

To support multiple resolutions, you can create icons of different resolutions and place them in the correct folders.

  • Low density
    • res/drawable-ldpi
    • 36×36 resolution
  • Medium density
    • res/drawable-mdpi
    • 48×48 resolution
  • High density
    • res/drawable-hdpi
    • 72×72 resolution
  • Extra high density
    • res/drawable-xhdpi
    • 96×96 resolution
Posted in Android at January 31st, 2009. 38 Comments.

Android button tutorial

A lot of people have found this site by searching for an Android button tutorial, so here it is.

  1. This tutorial assumes that you already have an activity and are using an XML layout.
  2. Open the layout XML and add the button element.  Assign an ID with the “@+id” operator.  The + tells Android to generate an ID for this element so that you can reference it in your Java files.
    1. This is an example. Your layout and text elements will probably be very different. In this example case, the ID of the button is “close”.
      <Button android:id="@+id/close"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_alignParentBottom="true"
          android:text="@string/title_close" />
  3. Open the activity class.  Add a class property to hold a reference to the button.
    private Button closeButton;
  4. If you haven’t already, override the onCreate method.
    @Override
    protected void onCreate(Bundle savedInstanceState) {
    }

    1. For this example, we don’t need the saved instance state, so ignore it.
  5. Now, in the onCreate method, attach a listener to the click event for the button.  This example will call “finish()” on the activity, the Android analog of clicking the close button on a window.
protected void onCreate(Bundle savedInstanceState) {
  this.setContentView(R.layout.layoutxml);
  this.closeButton = (Button)this.findViewById(R.id.close);
  this.closeButton.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
      finish();
    }
  });
}
  1. Here’s a short description of what’s happening.
    1. First, get the button ID.  The ID created earlier in the layout, “close”, is compiled by Android and assigned a unique integer ID which is available to the application through the “R” class, which I assume is short for “Resources”.
    2. Request a reference to the button from the activity by calling “findViewById”.  The button has to be retrieved from the activity because while an ID is unique in an activity, it is not unique among all activities.
    3. Assign the retrieved button to an instance variable so that if you need it later, you can easily find it without having to query for it again.
    4. Create a class implementing “OnClickListener” and set it as the on click listener for the button.

As UI elements go, buttons are some of the simplest.  Later, I’ll write about menus and dialogs, which aren’t so easy.

Posted in Android at January 31st, 2009. 96 Comments.

Loading string resources in Android

To support i18n, internationalization, Android provides a resource file, usually /res/values/strings.xml.  That XML and others are compiled and each resource is assigned a unique integer ID.  The IDs are placed into a resource file, “R”, as public static final variables.  Here’s how to get the value of a string resource in your application.

In a layout XML

android:text="@string/resource_name"

In an Activity

this.getString(R.string.resource_name)

In an area of the program in which you have access to a Context or Application, such as a ListAdapter.

context.getString(R.string.resource_name)
application.getString(R.string.resource_name)
Posted in Android at January 18th, 2009. 18 Comments.