Testing multiple properties with single assertion

18 May 2012

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"))));

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

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:

Testing object graphs

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:

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

Enjoy!!!

Blogs relacionados

Get content like this straight to your inbox!

Software es nuestra pasión.

Somos Software Craftspeople. Construimos software bien elaborado para nuestros clientes, ayudamos a los/as desarrolladores/as a mejorar en su oficio a través de la formación, la orientación y la tutoría. Ayudamos a las empresas a mejorar en la distribución de software.

Contacto

3 Sutton Lane, planta 3
Londres, EC1M 5PU

Teléfono: +44 207 4902967

2 Mount Street
Manchester, M2 5WQ

Teléfono: +44 161 302 6795

Carrer de Pallars 99, planta 4, sala 41
Barcelona, 08018

Teléfono: +34 937 82 28 82

Correo electrónico: hello@codurance.es