Pages

lundi 31 août 2015

Utiliser les Rules Junit mises à disposition dans les dernières versions de Mockito et Spring

J’ai déjà parlé sur ce blog des Rules introduites dans Junit à partir de la version 4.7. Aujourd'hui nous en sommes à la version 4.12 de Junit et petit à petit les différents frameworks commencent à fournir leur propre implémentations des Rules.

Pour rappel les Rules permettent de capitaliser du comportement technique entre vos tests sans passer par des classes abstraites ou par une annotation @RunWith qui ne peut être définie qu’une seule fois dans une classe. Vous pouvez utiliser plusieurs Rules par classes de tests, vous pouvez les chainer, ajouter du comportement avant/après l’instanciation de la classe, avant/après l’exécution d’une méthode de tests…

Je voulais dans cet article parler de deux frameworks que j’utilise Mockito et Spring qui ont tout deux mis à disposition des Rules dans leur dernière releases (Mockito 1.10.17 et Spring 4.2)

Mockito >= 1.10.7

Si nous revenons 3 ans en arrière avant Mockito 1.8.3 nous pouvions initié un test Mockito comme ceci

public class MockitoExample {
    private ConferenceRepository conferenceRepository;

    private DefaultFavoriteService defaultFavoriteService;

    private List<Conference> conferences = new ArrayList<>();

    @Before
    public void setup() {
        conferenceRepository = Mockito.mock(ConferenceRepository.class);
        defaultFavoriteService = new DefaultFavoriteService();
        defaultFavoriteService.setConferenceRepository(conferenceRepository);
    }
    
    //...
}

Les annotations @Mock et @InjectMocks ont permi de simplifier l'écriture de nos tests

@RunWith(MockitoJUnitRunner.class)
public class MockitoExample {
    @Mock
    private ConferenceRepository conferenceRepository;
    @InjectMocks
    private DefaultFavoriteService defaultFavoriteService;

    private List<Conference> conferences = new ArrayList<>();
    
    //...
}

Voici maintenant ce que nous pouvons faire avec une  Rule Junit

public class MockitoExample {
    @Rule
    public MockitoRule mockitoRule = MockitoJUnit.rule();
    @Mock
    private ConferenceRepository conferenceRepository;
    @InjectMocks
    private DefaultFavoriteService defaultFavoriteService;

    private List<Conference> conferences = new ArrayList<>();
    
    //...
}

Spring >= 4.2



La dernière version de Spring vient à peine de sortir et les Rules mises à disposition sont loin d'être des foctionnalités phares de cette version. Mais regardons comment les utiliser

Avant on écrivait le code suivant

@ContextConfiguration(classes = {ApplicationConfig.class})
@Transactional
@RunWith(SpringJUnit4ClassRunner.class)
public class TalkArchiverRepositoryImplTest  {

    @Autowired
    private TalkArchiverRepository talkArchiverRepository;

    @Autowired
    protected DataSource dataSource;
    
    //...
}

Maintenant voila  ce que vous devez faire pour utiliser les Rules Junit

public class TalkArchiverRepositoryImplTest  {

    @ClassRule
    public SpringClassRule springClassRule = new SpringClassRule();
    @Rule
    public SpringMethodRule classRule = new SpringMethodRule();
    
    @Autowired
    private TalkArchiverRepository talkArchiverRepository;

    @Autowired
    protected DataSource dataSource;
    
    //...
}

Vous pouvez remarquer que nous utilisons deux Rules : une liée à la création/destruction de la classe et une autre liée à l'exécution des méthodes de tests. Cette utilisation est peut être un peu verbeuse et si vous ne deviez garder qu'une seule annotation @RunWith, ce serait peut être celle liée à Spring.

2 commentaires:

  1. Et que deviennent la référence à ApplicationConfig et l'annotation Transactional dans l'exemple Spring? Elles restent là? Les deux rules remlacent uniquement le RunWith, c'est ça?

    RépondreSupprimer
  2. Oui les rules ne concernent que le RunWith

    RépondreSupprimer

Remarque : Seul un membre de ce blog est autorisé à enregistrer un commentaire.