mardi 21 février 2012

assertThat( myBlog, is( beautiful() ) );

Vous connaissez sûrement cette chanson que me chantait ma grand-mère à la période de l'année où l'on mange cette galette qui couronne des rois ?

J'aime les assert savez vous comment ?
Quand elles sont bien faites avec des matcher dedans!

Trêve de fariboles, j'aurai pu intitulé ce billet "Introduction aux assertions avec JUnit" mais je suis encore loin de cette prétention. Jugez vous-même.

C'est quoi un beau test unitaire?

C'est un long débat que je n'aborderai pas ici. Cependant, il y a une façon d'écrire un test de façon à faire transparaître l'intention du développeur à ce moment, c'est d'employer les assertions par la méthode assertThat().

Quoi! assertTrue ( monTrucQuiDoitEtreTrue ); c'est pas bien?

Si biensûr c'est un bon début :

List users = userService.findUsersLivingIn("hollywood");
assertFalse( "Il est où Schwarzy?", users.isEmpty() );

Cet exemple montre que notre service fonctionne bien, mais l'alternative suivante me donne plus envie d'écrire et maintenir des tests :

List users = userService.findUsersLivingIn("hollywood");
assertThat( users, is( not( empty() ) ) );

Dingue! j'ai l'impression de lire ma spec ... en anglais, mais comment est-ce possible ?

Vous aurez probablement reconnu la méthode statique assertThat(Objet, Matcher<T>), fournie par la classe org.junit.Assert. Cette méthode a une signature simple: un sujet et un Matcher capable de valider le bon état du sujet.
Les deux autres méthodes is(Matcher<T>) et not(Matcher<T>) sont également statiques et fournies cette fois-ci par la classe org.hamcrest.CoreMatchers.

OK mais la méthode empty(), elle sort d'où ?

C'est une implémentation que l'interface Matcher<T> complétant l'offre relativement abondante de la librairie JUnit.

static public Matcher<Collection<?>> empty()
{
    // OK on implémente pas Matcher mais on étend BaseMatcher,
    // suis pas encore sûr de comprendre pourquoi à l'heure où j'écrit ces lignes
    return new BaseMatcher<Collection<?>>()
    {
        /**
         * On indique ici le texte d'aide en cas d'échec.
         */
        @Override
        public void describeTo( Description description )
        {
            description.appendText( " empty" );
        }

        /**
         * C'est en partie ici que la magie opère.
         */
        @Override
        public boolean matches( Object item )
        {
            if ( item instanceof Collection<?> )
            {
                return ( (Collection<?>) item ).isEmpty();
            }
            return false;
        }
    };
}

Certes ça fait un bout de code conséquent mais cela constitue un premier élément de notre boîte à outil de Matchers. Je ne serai pas surpris de voir fleurir des librairies incluant d'autres Matchers pour différents usages.

Bref, les assert c'est bon, mangez en !

Enjoy :)

3 commentaires:

  1. As tu déja essayé FestAssert ?
    Je trouve les assertions encore plus lisibles.

    RépondreSupprimer
  2. Effectivement, c'est la fête de l'assertion. J'avais déjà essayé mais pas eu le réflexe de m'en servir ... jusqu'à présent ;)

    RépondreSupprimer
  3. Pour plus de doc :
    http://docs.codehaus.org/display/FEST/Fluent+Assertions+Module

    RépondreSupprimer