I am trying to write some unit tests for Android and I'm getting hung up on whether my current code is unit testable or if I really need to break it down into smaller chunks to enable unit testing. Note that I'm referring to unit tests that don't require an emulator and just run on the JVM.
I currently have the following method which is part of a View object. It receives a MotionEvent object from the framework and uses the information contained within the MotionEvent object to translate the View by setting the x/y coordinates of the view:
public void performDrag(MotionEvent event) {
int originalLeft = getLeft();
int originalTop = getTop();
int originalWidth = getWidth();
int originalHeight = getHeight();
float currentPointerX = event.getRawX();
float currentPointerY = event.getRawY();
float deltaX = currentPointerX - mOriginalX;
float deltaY = currentPointerY - mOriginalY;
mOriginalX = currentPointerX;
mOriginalY = currentPointerY;
int updatedLeft = originalLeft + (int) deltaX;
int updatedTop = originalTop + (int) deltaY;
setLeft(updatedLeft);
setTop(updatedTop);
setRight(updatedLeft + originalWidth);
setBottom(updatedTop + originalHeight);
}
Here's the unit test (which doesn't run because of errors, not failed tests, but NPEs and other errors thrown during the test):
@Test
public void testPerformHitAndDrag() throws Exception {
MotionEvent motionEventDown = MotionEvent.obtain(1000,
1000, MotionEvent.ACTION_DOWN, 300, 300, 1, 1,
KeyEvent.getModifierMetaStateMask(), 1, 1, 0, 0);
MotionEvent motionEventMove = MotionEvent.obtain(1000,
1000, MotionEvent.ACTION_MOVE, 305, 305, 1, 1,
KeyEvent.getModifierMetaStateMask(), 1, 1, 0, 0);
MotionEvent motionEventUp = MotionEvent.obtain(1000,
1000, MotionEvent.ACTION_UP, 305, 305, 1, 1,
KeyEvent.getModifierMetaStateMask(), 1, 1, 0, 0);
mCustomView.onTouchEvent(motionEventDown);
Assert.assertTrue(((ColorDrawable) mCustomView.getBackground()).getColor() == Color.RED);
mCustomView.onTouchEvent(motionEventMove);
mCustomView.onTouchEvent(motionEventUp);
Assert.assertEquals(305, mCustomView.getLeft());
Assert.assertEquals(305, mCustomView.getTop());
}
When I run the test I get NPEs because the MotionEvents that I'm trying to create are always null.
Should it be possible to create a non-null MotionEvent in a unit test (vs. in an integration test where I actually have an emulator running)?
The only other way I can see to solve the problem would be to create a new class, let's call it, DragHandler, that had public methods on it that would accept x/y values as its parameters instead of MotionEvent. Then in onTouchEvent I could create a new instance of DragHandler and call its public methods. This would mean that DragHandler could be easily tested in isolation to ensure that it did the math correctly for a drag event. However I'm not sure if that's taking things too far and if I should be able to perform the testing as I originally described.
Aucun commentaire:
Enregistrer un commentaire