Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Testing Multiple Properties With a Single Assertion

DZone's Guide to

Testing Multiple Properties With a Single Assertion

· Java Zone ·
Free Resource

Verify, standardize, and correct the Big 4 + more– name, email, phone and global addresses – try our Data Quality APIs now at Melissa Developer Portal!

Every time I was trying to test an object's properties I was neither satisfied writing very verbose tests nor in using some of the out of the box hamcrest matchers. Although using the matchers was a big help, I never managed to make them read the way I wanted.

Another thing that was very important to me, I wanted to have a single assertion per method and a very descriptive description if the test did not pass.

I've decided to write my own matcher and hopefully it will be useful to other people. So, that's what I've done:

BeanMatcher

Hamcrest matcher to match multiple attributes of an object within a single assertion.

How to use it

// Static imports
    
    import static org.craftedsw.beanpropertymatcher.matcher.BeanMatcher.has;
    import static org.craftedsw.beanpropertymatcher.matcher.BeanPropertyMatcher.property;
    import static org.hamcrest.MatcherAssert.assertThat;
    import static org.hamcrest.Matchers.equalTo;
    import static org.hamcrest.Matchers.greaterThan;

    // Imagine that you have a method that returns an object Person

    Person person = new Person();
    person.setFirstName("Sandro");
    person.setAge(25);
    person.setLastName("Mancuso");
    
    // Then you can test it like that
    
    assertThat(person, has(
                            property("firstName", equalTo("Another dude")), // Mistmatch
                            property("age", greaterThan(18)), // Use any matcher
                            property("lastName", equalTo("Mancuso"))));

NOTE: Make sure you are using org.hamcrest.MatcherAssert.assertThat instead of the JUnit one.

If you run this test, you will get a message like

java.lang.AssertionError:
        Expected: property "firstName" = "Another dude"
        but: property "firstName" was "Sandro"

Now, change the age check to 

   property("age", greaterThan(60)) 

And you should get:

java.lang.AssertionError:
        Expected: property "firstName" = "Another dude" , property "age" = a value greater than <60>
        but: property "firstName" was "Sandro" , property "age" <25> was less than <60>

 

Testing object graphs

You can also do this

Person person = new Person();
    person.setFirstName("Sandro");
    person.setAge(35);
        
    Country uk = new Country();
    uk.setName("United Kingdom");
        
    Address address = new Address();
    address.setPostcode("1234556");
    address.setCity("London");
    address.setCountry(uk);
        
    person.setAddress(address);
        
    assertThat(person, has(
                            property("firstName", equalTo("Sandro")),
                            property("age", greaterThan(18)),
                            property("address.city", equalTo("London")),
                            property("address.postcode", equalTo("1234556")),
                            property("address.country.name", equalTo("United Kingdom")))); 

I use a combination of two matchers to do that:
- BeanMatcher: Provides the "has" method responsible to group all the property matchers.
- BeanPropertyMatcher: Provides the "property" method.

I expect to make more changes to them, so for the most up-to-date version, please check BeanMatcher on my github account.
 

 

 

Developers! Quickly and easily gain access to the tools and information you need! Explore, test and combine our data quality APIs at Melissa Developer Portal – home to tools that save time and boost revenue. Our APIs verify, standardize, and correct the Big 4 + more – name, email, phone and global addresses – to ensure accurate delivery, prevent blacklisting and identify risks in real-time.

Topics:

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}