Automating number picker in android using espresso

There is a problem with accepted answer : it does not fire on change event. So (if you need it) you can't test if your view react to this on change event.

The following code (kotlin) is not cool anyway but i think it's the only way.

fun setValue(value: Int): ViewAction {
    return object : ViewAction {
        override fun getDescription(): String {
            return "set the value of a " + NumberPicker::class.java.name
        }

        override fun getConstraints(): Matcher<View> {
            return ViewMatchers.isAssignableFrom(NumberPicker::class.java)
        }

        // the only way to fire onChange event is to call this private method
        override fun perform(uiController: UiController?, view: View?) {
            val numberPicker = view as NumberPicker

            val setValueMethod = NumberPicker::class.java.getDeclaredMethod(
                "setValueInternal",
                Int::class.java,
                Boolean::class.java
            )

            setValueMethod.isAccessible = true

            setValueMethod.invoke(numberPicker, value, true)
        }
    }
}

For those looking at this question later (like me) this might be helpful: DateTimePickerTest makes use of PickerActions. PickerActions allows code for date pickers like this (Java):

onView(withClassName(Matchers.equalTo(DatePicker.class.getName()))).perform(PickerActions.setDate(year, month + 1, day));

Or for time pickers (Kotlin):

onView(withClassName(Matchers.equalTo(TimePicker::class.java.name))).perform(PickerActions.setTime(0, 10))

Match the view and then perform the action:

ViewInteraction numPicker = onView(withClassName(Matchers.equalTo(NumberPicker.class.getName())));
numPicker.perform(setNumber(1));

Create a ViewAction to set the number:

public static ViewAction setNumber(final int num) {
    return new ViewAction() {
        @Override
        public void perform(UiController uiController, View view) {
            NumberPicker np = (NumberPicker) view;
            np.setValue(num);

        }

        @Override
        public String getDescription() {
            return "Set the passed number into the NumberPicker";
        }

        @Override
        public Matcher<View> getConstraints() {
            return ViewMatchers.isAssignableFrom(NumberPicker.class);
        }
    };
}

To match a View by its class name you can simply use:

 onView(withClassName(Matchers.equalTo(TimePicker.class.getName())));

Once you have the ViewInteraction object you can set a value on it defining and using a ViewAction as following:

public static ViewAction setTime(final int hour, final int minute) {
        return new ViewAction() {
            @Override
            public void perform(UiController uiController, View view) {
                TimePicker tp = (TimePicker) view;
                tp.setCurrentHour(hour);
                tp.setCurrentMinute(minute)
            }
            @Override
            public String getDescription() {
                return "Set the passed time into the TimePicker";
            }
            @Override
            public Matcher<View> getConstraints() {
                return ViewMatchers.isAssignableFrom(TimePicker.class);
            }
        };
    }