简体   繁体   中英

How to mock MotionEvent and SensorEvent for Unit Testing in android?

How to unit test android SensorEvent and MotionEvent classes?

I need to create one MotionEvent object for Unit testing. (We have obtain method for MotionEvent that we can use after mocking to create MotionEvent custom object )

For MotionEvent class, I have tried with Mockito like:

MotionEvent Motionevent = Mockito.mock(MotionEvent.class);

But following error I am getting on Android Studio:

java.lang.RuntimeException:

Method obtain in android.view.MotionEvent not mocked. See https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support for details.
    at android.view.MotionEvent.obtain(MotionEvent.java)

Following the site mentioned on this error, I have added

testOptions {
        unitTests.returnDefaultValues = true
    }

on build.gradle, but still I am getting this same error. Any idea on this?

I have finally implemented it for MotionEvent by using Roboelectric

import android.view.MotionEvent;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.annotation.Config;

import static org.junit.Assert.assertTrue;

import org.robolectric.RobolectricGradleTestRunner;

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class)
public class ApplicationTest {

    private MotionEvent touchEvent;

    @Before
    public void setUp() throws Exception {
        touchEvent = MotionEvent.obtain(200, 300, MotionEvent.ACTION_MOVE, 15.0f, 10.0f, 0);
    }
    @Test
    public void testTouch() {
      assertTrue(15 == touchEvent.getX());
    }
}

How can we do the same thing for SensorEvents ?

Here's how you could mock a SensorEvent for an accelerometer event:

private SensorEvent getAccelerometerEventWithValues(
         float[] desiredValues) throws Exception {
    // Create the SensorEvent to eventually return.
    SensorEvent sensorEvent = Mockito.mock(SensorEvent.class);

    // Get the 'sensor' field in order to set it.
    Field sensorField = SensorEvent.class.getField("sensor");
    sensorField.setAccessible(true);
    // Create the value we want for the 'sensor' field.
    Sensor sensor = Mockito.mock(Sensor.class);
    when(sensor.getType()).thenReturn(Sensor.TYPE_ACCELEROMETER);
    // Set the 'sensor' field.
    sensorField.set(sensorEvent, sensor);

    // Get the 'values' field in order to set it.
    Field valuesField = SensorEvent.class.getField("values");
    valuesField.setAccessible(true);
    // Create the values we want to return for the 'values' field.
    valuesField.set(sensorEvent, desiredValues);

    return sensorEvent;
}

Change the type or values as appropriate to your use case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM