javajunit4hamcrestassertthat

Hamcrest Pattern Assert 2 Properties of Custom Collection


I have a Java Custom Object collection List<Employee> with two (2) properties. It is received as a response of Web Service. The object seems like

public class Employee{
   public String getName(){ ... }
   public String getDesignation(){ ... }
}

I need to write an assertion to check if the name of the employee is David then its designation must be Manager. I tried it like that

assertThat(employeeList, allOf(hasItem(hasProperty("name", equalTo("David"))) , hasItem(hasProperty("designation", equalTo("Manager")))));

but it passed if there is at least one Manager instance and one David. My requirement is to apply these two checks on a single instance.

Please help.


Solution

  • Given a class Foo:

    public class Foo {
        private String name;
        private String designation;
    
        public Foo(String name, String designation) {
            this.name = name;
            this.designation = designation;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getDesignation() {
            return designation;
        }
    
        public void setDesignation(String designation) {
            this.designation = designation;
        }
    }
    

    And a custom Hamcrest matcher:

    private static class FooMatcher extends BaseMatcher<List<Foo>> {
        public String name;
        public String designation;
    
        public static FooMatcher matches(String name, String designation) {
            return new FooMatcher(name, designation);
        }
    
        private FooMatcher(String name, String designation) {
            this.name = name;
            this.designation = designation;
        }
    
        @Override
        public boolean matches(Object item) {
            Foo foo = (Foo) item;
            return foo.getName().equals(name) && foo.getDesignation().equals(designation);
        }
    
        @Override
        public void describeTo(Description description) {
            // this is a quick impl, you'll probably want to fill this in!
        }
    }
    

    This test will pass:

    @Test
    public void canAssertOnMultipleFooAttributes() {
        List<Foo> incoming = Lists.newArrayList(new Foo("bill", "sir"), new Foo("bob", "mr"), new Foo("joe", "mr"));
        assertThat(incoming, hasItem(FooMatcher.matches("bob", "mr")));
    }