Skip to content

Instantly share code, notes, and snippets.

@Sloy
Created February 26, 2015 12:50
Show Gist options
  • Save Sloy/d59a36e6c51214d0b131 to your computer and use it in GitHub Desktop.
Save Sloy/d59a36e6c51214d0b131 to your computer and use it in GitHub Desktop.
MockParcel for testing Parcelables implementations with the new Android's Unit testing support (http://tools.android.com/tech-docs/unit-testing-support). Only String and Long read/write implemented here. Add mock methods for other types.
import android.os.Parcel;
import java.util.ArrayList;
import java.util.List;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
public class MockParcel {
public static Parcel obtain() {
return new MockParcel().getMockedParcel();
}
Parcel mockedParcel;
int position;
List<Object> objects;
public Parcel getMockedParcel() {
return mockedParcel;
}
public MockParcel() {
mockedParcel = mock(Parcel.class);
objects = new ArrayList<>();
setupMock();
}
private void setupMock() {
setupWrites();
setupReads();
setupOthers();
}
private void setupWrites() {
Answer<Void> writeValueAnswer = new Answer<Void>() {
@Override public Void answer(InvocationOnMock invocation) throws Throwable {
Object parameter = invocation.getArguments()[0];
objects.add(parameter);
return null;
}
};
doAnswer(writeValueAnswer).when(mockedParcel).writeLong(anyLong());
doAnswer(writeValueAnswer).when(mockedParcel).writeString(anyString());
}
private void setupReads() {
when(mockedParcel.readLong()).thenAnswer(new Answer<Long>() {
@Override public Long answer(InvocationOnMock invocation) throws Throwable {
return (Long) objects.get(position++);
}
});
when(mockedParcel.readString()).thenAnswer(new Answer<String>() {
@Override public String answer(InvocationOnMock invocation) throws Throwable {
return (String) objects.get(position++);
}
});
}
private void setupOthers() {
doAnswer(new Answer<Void>() {
@Override public Void answer(InvocationOnMock invocation) throws Throwable {
position = ((Integer) invocation.getArguments()[0]);
return null;
}
}).when(mockedParcel).setDataPosition(anyInt());
}
}
@hram
Copy link

hram commented Mar 29, 2018

this does not work if Parcelable class has nullable String field

@milosmns
Copy link

I made some edits to this approach (and also converted it to Kotlin) - you can check it out here: https://gist.github.com/milosmns/7f6448a3602595948449d3bfaff9b005
It's a good approach overall, I've been able to test everything I needed using this.

@sienatime
Copy link

In Mockito 2, you can switch to the nullable matcher to make this match null strings as well:

doAnswer(answer).when(mParcel).writeString(nullable(String.class));

anyString() used to also match null, but it doesn't anymore: mockito/mockito#185

Also works for nullable Parcelables.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment