Tester le javascript : JSUnit, JSmock, Jstester (partie 2)
Par MD3804-GANDI le mardi 26 janvier 2010, 13:16 - Tests / XUnit - Lien permanent
Après le billet consacré à JsUnit et celui qui expliquait comment mocker une requête Ajax, nous allons maintenant voir comment mocker en javascript. Pour cela je vous propose une courte présentation de JsMock. Les exemples de code sont en annexe de ce billet.
Pour montrer les capacités de JsMock, rien de tel que des exemples de code. Nous allons donc reprendre le code du premier billet (vous pouvez télécharger les sources en annexe du premier billet)
Installation
La première chose à faire est de télécharger JsMock et de l'ajouter dans
le répertoire JsUnit (ou ailleurs, mais le tout est d'être cohérent lors de la
déclaration dans le fichier HTML) , puis de l'importer à partir de notre
fichier de tests SimpleCodeTest
:
<script language="JavaScript" type="text/javascript" src="../jsmock.js"></script>
Exemple de code à mocker
Pour comprendre les mocks il vaux mieux faire interagir deux objets entre
eux : cela permet de tester un objet et d'en mocker un autre. Ajoutons
donc un objet ConfigParameter
et définissons en une instance dans
MyObjectToTest :
function ConfigParameter() { this.getAlertMessage = function(){ return "alertMessage"; } this.setParam = function(Aname, Avalue) { //this[name]=value } } function MyObjectToTest(){ this.configParameter = new ConfigParameter(); var message = "Not defined yet!"; this.setMessage = function(messageParam){ message = messageParam } this.getMessage = function(){ return message; } this.getAlertMessage = function(){ return this.configParameter.getAlertMessage(); } this.setConfigValue = function(){ this.configParameter.setParam("MyName", "MyValue"); } }
Mocker des valeurs de retour
Voici un exemple où nous allons mocker le retour de
getAlertMessage
:
function testMockReturnedValue() { // Actor MyObj = new MyObjectToTest(); // Mock mockControl = new MockControl(); mockConfig = mockControl.createMock(ConfigParameter); mockConfig.expects().getAlertMessage().andReturn("mock Alert Message"); MyObj.configParameter = mockConfig; // Assert assertEquals("mock Alert Message", MyObj.getAlertMessage()); mockControl.verify(); }
Vous remarquerez qu'à la différence de EasyMock en Java, il n'est pas
nécessaire d'appeler la méthode replay()
La méthode vérify
permet de vérifier que les méthodes mockées
sont bien appelées le bon nombre de fois : si une méthode non défini par
votre mock est appelée le test ne passera pas, en revanche vous pourriez avoir
défini le comportement d'une méthode mais que cette dernière ne soit jamais
appelée, dans ce cas, si vous n'appelez pas la méthode verify
, le
test passera mais vous ne saurez pas que la méthode n'a pas été appelée).
mocker des fonctions
Il est possible de simuler les comportement (le corps de la méthode) d'une
fonction grâce à la méthode andStub
:
function testStubFunction() { // Actor MyObj = new MyObjectToTest(); // Mock mockControl = new MockControl(); mockConfig = mockControl.createMock(ConfigParameter); mockConfig.expects().getAlertMessage().andStub( function() { return "test"; } ); MyObj.configParameter = mockConfig; // Assert assertEquals("test", MyObj.getAlertMessage()); }
Simuler des exceptions
Il est également possible de simuler des exceptions avec la méthode
andThrow
:
function testThrow() { exception = false ; // Actor MyObj = new MyObjectToTest(); // Mock mockControl = new MockControl(); mockConfig = mockControl.createMock(ConfigParameter); mockConfig.expects().getAlertMessage().andThrow("Error !"); MyObj.configParameter = mockConfig; try { MyObj.getAlertMessage(); } catch (e){ exception = true; } assertEquals(true, exception); }
Mocker des fonctions avec paramètres
Pour mocker une fonction avec des paramètres, vous avez deux
possibilités : soit vous spécifiez le type des paramètres lors de la
définition du mock, dans le cas où seul le type des paramètres vous importe.
Pour cela utiliser TypeOf.isA()
function testFunctionWithTypedParameters() { // Actor MyObj = new MyObjectToTest(); // Mock mockControl = new MockControl(); mockConfig = mockControl.createMock(ConfigParameter); mockConfig.expects().setParam(TypeOf.isA(String),TypeOf.isA(String)); MyObj.configParameter = mockConfig; MyObj.setConfigValue(); mockControl.verify(); }
soit vous spécifiez la valeur des paramètres, si vous voulez vérifier que la fonction est appelée avec les bonnes valeurs :
function testFunctionWithParameters() { // Actor MyObj = new MyObjectToTest(); // Mock mockControl = new MockControl(); mockConfig = mockControl.createMock(ConfigParameter); mockConfig.expects().setParam("MyName", "MyValue"); MyObj.configParameter = mockConfig; MyObj.setConfigValue(); mockControl.verify(); }
J'espère que cela vous à donner envie de l'utiliser, car le Javascript est de plus en plus présent dans les applications web et les tests permettent de mieux découpler votre code et de le rendre plus robuste.
La troisième et dernière partie traitera de JsTester
qui permet
de tester du javascript coté serveur (JsUnit dispose d'une partie serveur mais
elle n'est là que pour piloter les tests, il faut toujours avoir un
navigateur). nous verrons ses avantages et ses inconvénients et comment
l'intégrer avec Maven et JUnit.