I am a newbie in Android and Robolectric. I am trying to simulate (as the topic indicates it) a drag event on a viewpager.
I have ever implemented this code and it runs on the emulator.
The matter is mostly: how can I unit test it?
Here is the unit test:
/** imports are skipped **/
@RunWith(RobolectricTestRunner.class)
@Config(manifest = "/src/main/AndroidManifest.xml")
public class TestImages {
private ImageActivity activity;
@InjectResource(R.drawable.ic_launcher)
private static Drawable image;
@Spy
private final PicturesModel picturesModel = spy(new PicturesModelImpl());
/**
* Last touched view
*/
private View lastTouchView;
/**
* Last touched X coordinate
*/
private float lastTouchX;
/**
* Last touched Y coordinate
*/
private float lastTouchY;
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
final Module roboGuiceModule = RoboGuice.newDefaultRoboModule(Robolectric.application);
final Module pictureModule = Modules.override(roboGuiceModule).with(new PictureModule());
final Module testModule = Modules.override(pictureModule).with(new TestPictureModule(picturesModel));
RoboGuice.setBaseApplicationInjector(Robolectric.application, RoboGuice.DEFAULT_STAGE, testModule);
RoboInjector injector = RoboGuice.getInjector(Robolectric.application);
injector.injectMembersWithoutViews(this);
}
@Test
public void scroll_image() {
final Intent intent = new Intent(Robolectric.getShadowApplication().getApplicationContext(), ImageActivity.class);
final Album album = new Album(1, "album_1", image);
intent.putExtra("album", album);
intent.putExtra("position", 2);
intent.putExtra("imageId", 2L);
// Get the activity
activity = Robolectric.buildActivity(ImageActivity.class).withIntent(intent).create().get();
final Point point = new Point();
activity.getWindowManager().getDefaultDisplay().getSize(point);
// Get a spy viewer otherwise viewPager's width is always 0
final ViewPager viewPager = spy((ViewPager) activity.findViewById(R.id.viewPager));
viewPager.setVisibility(View.VISIBLE);
when(viewPager.getWidth()).thenReturn(point.x - 50);
// First item sent by viewPager before swipe
final int firstItem = viewPager.getCurrentItem();
// Swipe
drag(viewPager, 10F, 10F, point.x - 60F, 10F);
// Next item after swipe
final int secondItem = viewPager.getCurrentItem();
// Comparison
assertThat(firstItem).isEqualTo(2);
assertThat(secondItem).isEqualTo(3);
}
public void touchDown(View view, float x, float y) {
lastTouchX = x;
lastTouchY = y;
lastTouchView = view;
sendMotionEvent(view, MotionEvent.ACTION_DOWN, x, y);
}
public void touchMove(float x, float y) {
lastTouchX = x;
lastTouchY = y;
sendMotionEvent(lastTouchView, MotionEvent.ACTION_MOVE, x, y);
}
public void touchUp() {
sendMotionEvent(
lastTouchView, MotionEvent.ACTION_UP, lastTouchX, lastTouchY);
lastTouchView = null;
}
public void drag(View view, float xStart, float yStart,
float xEnd, float yEnd) {
touchDown(view, xStart, yStart);
touchMove(xEnd, yEnd);
touchUp();
}
private void sendMotionEvent(View view, int action, float x, float y) {
int[] screenOffset = new int[2];
view.getLocationOnScreen(screenOffset);
MotionEvent event = MotionEvent.obtain(100, 200, action,
x + screenOffset[0], y + screenOffset[1], 0);
shadowOf(event).setPointerIds(1, 2);
shadowOf(event).setPointerIndex(1);
view.onTouchEvent(event);
view.dispatchTouchEvent(event);
}
}
and the the activity:
public class ImageActivity extends RoboActivity {
@Inject
private PicturesModel picturesModel;
@InjectView(R.id.viewPager)
private ViewPager viewPager;
private PagerAdapter pagerAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.image);
final Bundle bundle = getIntent().getExtras();
if (bundle != null && !bundle.isEmpty()) {
final long id = (long) bundle.get("imageId");
final int position = (int) bundle.get("position");
final Picture picture = picturesModel.getPicture(id);
if (picture != null) {
pagerAdapter = new ImageAdapter(this, picturesModel.getAllPictures((Album) bundle.get("album")));
viewPager.setAdapter(pagerAdapter);
viewPager.setCurrentItem(position, true);
}
}
}
}
and this is the layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/viewPager" />
Does someone has an idea how to proceed or to tell me where is my mistake?
I think you what you are looking for is the Espresso library.
It simulates UI Events and let you check the state of the view once you threw the event and it is really easy to use. Just don't forget to switch animations off in the developers settings.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With