Testing Multiple Properties With a Single Assertion
Join the DZone community and get the full member experience.Join For Free
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:
// 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
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.
Published at DZone with permission of Sandro Mancuso, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.