Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Android: Unit testing custom views

Tyler Schultz
Saturday, June 11, 2011

Android Activity classes can become gigantic and unwieldy if you’re not careful. Testing complex Activities requires complex setup. To reduce that pain we try our best to keep the Activity lean. This means getting logic out of the Activity. One technique we use is to create custom views that we can test in isolation.

Here is an example of a view class that starts out with a ProgressBar spinner, and when the text is set, the spinner is hidden, and the text becomes visible:

public class LoadingTextView extends RelativeLayout {
    ...
    public void stopLoadingAndSetText(int text_res_id) {
        TextView textView = (TextView) findViewById(loading_text_text_view);
        textView.setText(text_res_id);
        textView.setVisibility(VISIBLE);

        findViewById(loading_text_spinner).setVisibility(View.GONE);
    }
}

Here is the layout xml that is associated with the custom view class. Notice the reference to the LoadingTextView class in the outermost tag (which has lost its formatting!!!):

<?xml version="1.0" encoding="utf-8"?>

<com.pivotallabs.views.loadingtextview android:layout_height="wrap_content" android:layout_width="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">

    <linearlayout android:gravity="center" android:padding="10dip" android:orientation="horizontal" android:layout_height="wrap_content" android:id="@+id/loading_text_spinner" android:layout_width="fill_parent">
        <progressbar android:layout_height="wrap_content" android:layout_width="wrap_content" />
        <textview android:paddingLeft="10dip" android:text="Loading..." android:layout_height="wrap_content" android:layout_width="wrap_content" />
    </linearlayout>

    <textview android:visibility="invisible" android:layout_height="wrap_content" android:id="@+id/loading_text_text_view" android:layout_width="fill_parent" />

</com.pivotallabs.views.loadingtextview>

Robolectric will allow you to instantiate the Android subclasses in the JVM, but the problem is that newing the custom view class will not inflate the elements the view class expects to be present. To get around this you can take advantage of Robolectric’s simulated view inflating functionality. Use the LayoutInflator.from() method to get an inflator which can be used to inflate your view:

@RunWith(RobolectricTestRunner.class)
public class LoadingTextViewTest {
    private LoadingTextView loadingTextView;
    private View loadingSpinner;
    private TextView loadingTextTextView;

    @Before
    public void setUp() throws Exception {
        loadingTextView = (LoadingTextView) LayoutInflater.from(new Activity()).inflate(R.layout.loading_text, null);
        loadingSpinner = loadingTextView.findViewById(R.id.loading_text_spinner);
        loadingTextTextView = (TextView) loadingTextView.findViewById(R.id.loading_text_text_view);
    }

    @Test
    public void testStopLoadingAndSetTextShouldHideTheSpinnerAndShowTheTextView() throws Exception {
        assertThat(loadingSpinner.getVisibility(), equalTo(View.VISIBLE));
        assertThat(loadingTextTextView.getVisibility(), equalTo(View.INVISIBLE));

        loadingTextView.stopLoadingAndSetText(R.string.unit_tests_ftw);

        assertThat(loadingSpinner.getVisibility(), equalTo(View.GONE));
        assertThat(loadingTextTextView.getVisibility(), equalTo(View.VISIBLE));
    }

    @Test
    public void testStopLoadingAndSEtTextShouldSetTheTextOnTheTextView() {
        loadingTextView.stopLoadingAndSetText(R.string.unit_tests_ftw);

        assertThat((String) loadingTextTextView.getText(), equalTo("Unit Tests FTW!!!"));
    }
}

You can run these example tests yourself by checking out the RobolectricSample project on github.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Add New Comment Cancel reply

Your email address will not be published.

Tyler Schultz

Tyler Schultz
San Francisco

Recent Posts

  • [Standup][SF] 09/21/12: Get older faster
  • Ah, ah, ah. Now, that was silly. Wouldn’t you agree, my bats? Ah, ah, ah.
  • [SF][Standup] 09/19/12: ActiveAdmin vs. RailsAdmin… Arrrggg!
Subscribe to Tyler's Feed

Author Topics

rails (5)
time (2)
css (1)
heroku (2)
javascript (1)
activerecord (1)
android (3)
robolectric (1)
tdd (1)
agile (7)
amazon (1)
default scope (1)
hudson (1)
rspec (1)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >