Prima di proseguire consiglio la lettura della
prima parte e della
seconda parte.
In questo post affronteremo l'argomento dei mock object. Una prima tentazione potrebbe essere quella di cercare una libreria di mock per
Javascript, ma vista la sua natura dinamica proviamo a farne a meno.
Partiamo da un esempio per introdurre l'argomento. Supponiamo di voler testare il seguente metodo:
function show_alert(text) {
alert(text);
}
Ovviamente se eseguiamo tale metodo vedremo comparire una message box. Vediamo se riusciamo a testare l'interazione.
Per prima cosa occorre che quando viene chiamato alert venga eseguita una function nostra e non quella standard.
Occorre anche che quando il test termina l'esecuzione, venga ripristinata la vecchia function.
test("show alert", function() {
var old_alert = alert;
alert = function() {
};
show_alert('Ciao!');
alert = old_alert;
});
Se proviamo ad eseguire il metodo di test in QUnit vedremo che non viene più visualizzato l'alert.
In quanto abbiamo sostituito alert con una function vuota.
Questo a noi non basta perché vogliamo testare che venga chiamato alert con un certo parametro una sola volta.
Aggiungiamo quindi del comportamento al nostro mock.
test("show alert", function() {
var old_alert = alert;
var alert_call_count = 0;
alert = function() {
alert_call_count++;
};
show_alert('Ciao!');
equals(alert_call_count, 1);
alert = old_alert;
});
Il test sta diventando illegibile, facciamo un primo passo portando il codice di setup nel setup del modulo.
In QUnit si possono dichiarare dei moduli che assomigliano agli attributi Setup e TearDown delle Fixture di NUnit.
Ecco un esempio di dichiarazione di modulo con i metodi setup e teardown:
module("module name", {
setup: function() {
// setup code
},
teardown: function() {
// teardown code
}
})
Proviamo ad applicare il concetto appena esposto al test precedente:
var old_alert;
var alert_call_count = 0;
module("show alert", {
setup: function() {
old_alert = alert;
alert_call_count = 0;
alert = function() {
alert_call_count++;
};
},
teardown: function() {
alert = old_alert;
}
})
test("show alert", function() {
show_alert('Ciao!');
equals(alert_call_count, 1);
});
Il test si è accorciato notevolmente, ma se abbiamo mock più complicati il codice del setup diventerebbe presto molto complicato.
La logica precedente comunque si puo' estrarre un oggetto Mock in modo da semplificare la scrittura dei test.
Per testare il parametro passato si puo' procedere in maniera simile basta salvarsi il valore in una variabile e poi fare la assert su quel valore.