GestureDetector with Robolectric

546 views
Skip to first unread message

Benjamin Layet

unread,
Aug 1, 2013, 7:19:23 AM8/1/13
to robol...@googlegroups.com
I am using the GestureDetector in my app and it works fine on a real device.
When testing with Robolectric, it does not call back the listener after simulating an ACTION_DOWN event.


Activity:
public class MainActivity extends Activity {

public GestureHandler gestureHandler = new GestureHandler();
public GestureDetector detector ;
public TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.hello_world);
detector = new GestureDetector(this, gestureHandler);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
detector.onTouchEvent(event);
tv.setText("Gesture: " + gestureHandler.gesture);
return true;
}


}

GestureHandler:
public class GestureHandler extends SimpleOnGestureListener
{

public String gesture ="";
@Override
public boolean onDown(MotionEvent e) {
gesture = "onDown";
return true;
}
}

Test:
@RunWith(RobolectricTestRunner.class)
public class SimpleGestureDetectorTest {

private boolean eventSent = false;
MainActivity activity;

@Before
public void setUp() {
activity = Robolectric.buildActivity(MainActivity.class).create().get();
}

@Test
public void testCurrentThreadActionDown() {

currentThreadActionDown(200, 400);
assertEquals("onDown", activity.gestureHandler.gesture);
}

@Test
public void testUiThreadActionDown() throws InterruptedException {

final Object mutex = new Object();

activity.runOnUiThread(new Runnable() {

@Override
public void run() {
currentThreadActionDown(200, 400);
synchronized (mutex) {
eventSent = true;
mutex.notifyAll();
}
}
});

synchronized (mutex) {
if (!eventSent) {
mutex.wait(5000);
}

if (!eventSent) {
fail("Event not sent in UI thread");
}
}
// Assert that the event was properly forwarded
assertEquals("onDown", activity.gestureHandler.gesture);
}

private void currentThreadActionDown(float x, float y) {
long downTime = SystemClock.uptimeMillis();
// Obtain MotionEvent object
MotionEvent motionEvent = MotionEvent.obtain(downTime, // time of first
// down
downTime, // time of event
MotionEvent.ACTION_DOWN, // type of event
x, y, // event origin
0 // meta state
);
// send event directly to the activity
activity.onTouchEvent(motionEvent);
motionEvent.recycle();
}

}

Both tests fail : in UI thread and in current thread.
If  UI thread test is executed within an instrumentation test on a real device, it does not fail.

Is there a way to use Robolectric when using GestureDetector and ScaleGestureDetector ?

Benjamin Layet

unread,
Aug 1, 2013, 9:24:14 AM8/1/13
to robol...@googlegroups.com
Additional info: this was executed with robolectric-2.2-20130730.193729-26-jar-with-dependencies.jar

Jake Wharton

unread,
Aug 1, 2013, 11:53:33 AM8/1/13
to robol...@googlegroups.com

I can't speak to what the actual implementation of GestureDetector in Robolectric is, but I will say that you are probably testing the wrong thing. If you know that the GestureDetector calls your onTouchEvent method then you should be calling that method directly from your test. This way you are testing how your application reacts to an event rather than testing the fact that Android calls the callback. This is the spirit of unit tests. You want to test how your code handles situations rather than how Android behaves.

Your test should probably be something more like this:

    MainActivity activity;

    @Before
    public void setUp() {
        activity = Robolectric.buildActivity(MainActivity.class).create().get();
    }

    @Test

    public void testActionDownSetsTextViewText() {
        activity.gestureHandler.gesture = "onDown";
        activity.onTouchEvent(MotionEvent.obtain(20, System.currentTimeMillis(), ACTION_DOWN, 200, 400, 0));
        assertEquals("Gesture: onDown", activity.tv.getText().toString());
    }
--
You received this message because you are subscribed to the Google Groups "Robolectric" group.
To unsubscribe from this group and stop receiving emails from it, send an email to robolectric...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages