Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Request: Lambda Matcher #300

Open
Rhobal opened this issue Apr 30, 2020 · 4 comments
Open

Request: Lambda Matcher #300

Rhobal opened this issue Apr 30, 2020 · 4 comments

Comments

@Rhobal
Copy link

Rhobal commented Apr 30, 2020

Create a matcher that takes a lambda as type safe replacement of Matchers.hasProperty(propertyName, valueMatcher)

Sample code:

public class LambdaMatcher<T, S> extends BaseMatcher<T> {
    private final Function<T, S> lambda;
    private final String description;
    private Matcher<S> matcher;

    public LambdaMatcher(Function<T, S> lambda, Matcher<S> matcher,
                         String description) {
        this.lambda = lambda;
	this.matcher = matcher;
        this.description = description;
    }

    public LambdaMatcher(Function<T, S> lambda, Matcher<S> matcher) {
    	this(lambda, matcher, "");
    }

    @SuppressWarnings("unchecked")
    @Override
    public boolean matches(Object argument) {
        return matcher.matches(lambda.apply((T) argument));
    }

    @Override
    public void describeTo(Description description) {
        description.appendText(this.description);
    }
}

Usage:

assertThat(list, Matchers.hasItem(allOf(
   new LambdaMatcher<>(it -> it.getStringElem(), is("el1")),
   new LambdaMatcher<>(it -> it.getLongElem(), is(2L)))));
@tumbarumba
Copy link
Member

I'd love to get better support for lamdas and other Java 8 features into Hamcrest.

At the moment, Hamcrest 1.x works with Java 5 and greater, Hamcrest 2.x works with Java 7 and greater. For this feature, we'd have to increase the minimum supported version to Java 8.

Issues #206 and #207 discuss various ways we might go about doing that, though we haven't made much progress against those issues yet. I think this feature would have to depend upon those issues being completed first.

@DemianTinkiel
Copy link

Couldn't this be done via an extension? That would also alleviate some of the issues raised in #206 and #207 -> each extension can have their own minimal JDK version

@seregamorph
Copy link
Contributor

seregamorph commented Oct 9, 2020

You can try to use hamcrest-more-matchers (available on maven central). Your sample will look like

import static com.github.seregamorph.hamcrest.MoreMatchers.where;

    @Test
    public void test() {
        List<Item> list = Arrays.asList(new Item()
                .setStringElem("el-non-match")
                .setLongElem(2L));

        assertThat(list, hasItem(allOf(
                where(Item::getStringElem, is("el1")),
                where(Item::getLongElem, is(2L)))));
    }

    public static class Item {
        private String stringElem;
        private long longElem;

        public String getStringElem() {
            return stringElem;
        }

        public long getLongElem() {
            return longElem;
        }

        public Item setStringElem(String stringElem) {
            this.stringElem = stringElem;
            return this;
        }

        public Item setLongElem(long longElem) {
            this.longElem = longElem;
            return this;
        }
    }

Please note, the failed message will have convenient diagnostics (method reference resolved as string): after call Item.getStringElem

java.lang.AssertionError: 
Expected: a collection containing (Object that matches is "el1" after call Item.getStringElem and Object that matches is <2L> after call Item.getLongElem)
     but: Object that matches is "el1" after call Item.getStringElem was "el-non-match"

It works not only in Java 8, but also in Java 11 and 14.

@Rhobal
Copy link
Author

Rhobal commented Oct 14, 2020

Thanks, switched to hamcrest.MoreMatchers.where. Works like a charm

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants