1
\$\begingroup\$

I am new to android testing and would like to try start off in the correct direction, so I am trying to understand if this is the correct way to test a particular method or if there is some best practice that I should be following.

Here are some snippets of the class that contains the method I would like to test.

public class MapMarker implements Target {

private Bus mBus;
private RailsMarker mMarker;
private Bitmap mBitmap;

public String getGravatarUrl() {
    return mMarker.getGravatarUrl();
}

public String getUserId() {
    return mMarker.getUserId();
}

@Override
public void onBitmapLoaded(Bitmap bitmap, LoadedFrom loadedFrom) {
    System.out.println(String.format("loaded bit map from gravatar url = %s, for userid = %s",getGravatarUrl(), getUserId()));
    mBitmap = bitmap;
    mBus.post(new MarkerReadyEvent(this));          
    }
}

I am trying to test that when the onBitMapLoaded method is called, it posts a MarkerReadyEvent onto my eventbus.

Here is the test method I coded.

@Test
public void testOnBitMapLoaded() {
    Bus mockBus = mock(Bus.class);
    RailsMarker railsMarker = new RailsMarkerBuilder().withGravatarUrl("a_gravatar_url")
                                                      .withUserId("a_user_id")
                                                      .build();
    MapMarker androidMapMarker = new MapMarkerBuilder().withBus(mockBus)
                                                       .withMarker(railsMarker)
                                                       .build();
    androidMapMarker.onBitmapLoaded(null, null);
    verify(mockBus).post(isA(MarkerReadyEvent.class));
}

I am using Mockito to mock the eventbus. I am creating a real instance of the MapMarker class (via https://github.com/mkarneim/pojobuilder) I am also creating a RailsMarker instance to be included in the MapMarker instance. (I realized this in only needed for the println statement but I did not want to remove it just to make the test easier)

Is this a good approach or is there some other pattern I should be following? The part that seems a bit strange is that I end up building the instance I am going to test with both a mock object (the Bus) and a real object (the RailsMarker), but I don't see anyway around this.

\$\endgroup\$
3
\$\begingroup\$

You would be testing the MapMarker more in isolation if you would inject only mocks.

Isolation is important for two things:

  1. stability of test results
  2. more explicit and direct feedback

If a bug would be introduced in the RailsMarker, this test would also fail, causing it to be less stable. In case of this bug, there would by multiple test failures (also for RailsMarker and possibly other tests that use this class) making it harder to find the bug.

In general I would use mocks for any dependant object that has more logic than just getters and setters. That being said, it looks like the RailsMarker might qualify.

\$\endgroup\$
  • \$\begingroup\$ OK, so I guess I would do that by building my MapMarker instance with mock of the RailsMarker object that "implements" only the methods that are needed (getGravatarUrl() and getUserId()) to get thru the onBitMapLoaded method? I am not used to using mocks, so I need to learn how to effectively use them \$\endgroup\$ – nPn Aug 10 '14 at 23:25
  • \$\begingroup\$ @nPn yes, you build the mock in the same way, but you need to expect on it using when and specify the return value you want the mock to return. \$\endgroup\$ – Maarten Winkels Aug 10 '14 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.