Home » Android » android – Espresso Custom ViewMatcher Mismatch description not appearing in the log

android – Espresso Custom ViewMatcher Mismatch description not appearing in the log

Posted by: admin May 14, 2020 Leave a comment


I have written the following view matcher for my custom view

    public static Matcher<View> withValue(final Matcher<Long> longMatcher){
    return new BoundedMatcher<View, IntegerField>(IntegerField.class) {

        public void describeTo(Description description) {
            description.appendText("with value : ");

        public void describeMismatch(Object item, Description description) {
            super.describeMismatch(item, description);
            description.appendText("value=" + ((IntegerField)item).getValue());

        protected boolean matchesSafely(IntegerField field) {
            return longMatcher.matches(field.getValue());

when the match fails, the log doesn’t contain the mismatch description I appended in the descibeMismatch() function. Is there anything that I missed?

How to&Answers:

I had the same problem. Until the feature request is implemented, you can use a custom ViewAssertion that includes the mismatch reason:

public class EspressoUtils {
    // this class is copied from Espresso's source code
    // (we need to copy it so that we can replace the `assertThat` function it depends on
    private final static class MatchesViewAssertion implements ViewAssertion {
        final Matcher<? super View> viewMatcher;

        private MatchesViewAssertion(final Matcher<? super View> viewMatcher) {
            this.viewMatcher = viewMatcher;

        public void check(View view, NoMatchingViewException noViewException) {
            StringDescription description = new StringDescription();
            if (noViewException != null) {
                                "' check could not be performed because view '%s' was not found.\n",
                throw noViewException;
            } else {
                description.appendText("' doesn't match the selected view.");
                assertThat(description.toString(), view, viewMatcher);

         * A replacement for ViewMatchers.assertThat that includes the mismatch description (adapted from the source of ViewMatchers.assertThat
        private static <T> void assertThat(String message, T actual, Matcher<T> matcher) {
            if (!matcher.matches(actual)) {
                final StringDescription mismatch = new StringDescription();
                matcher.describeMismatch(actual, mismatch);

                Description description = new StringDescription();
                        .appendText("\nExpected: ")

                if(!mismatch.toString().trim().isEmpty()) {
                    description.appendText("\n    But: ").appendText(mismatch.toString());

                description.appendText("\n    Got: ");
                if (actual instanceof View) {
                    description.appendValue(HumanReadables.describe((View) actual));
                } else {
                throw new AssertionFailedError(description.toString());

    public static ViewAssertion matches(final Matcher<View> matcher) {
        return new MatchesViewAssertion(matcher);

Use it like this: