2015-06-21 10 views
6

Cosa voglio fare: Stiamo scrivendo alcuni test per una base di codice Javascript esistente che utilizza jQuery pesantemente. Per i test, non vogliamo avere veri e propri elementi HTML (fixture HTML). Preferiremmo se avessimo un oggetto mock jQuery che non faccia nulla legato all'HTML.Come simulare jQuery con Jasmine

mio punto di partenza: L'approccio più promettente che ho trovato qui:

http://eclipsesource.com/blogs/2014/03/27/mocks-in-jasmine-tests/

Questo crea un metodo di supporto che crea un finto passando attraverso le funzioni di un oggetto e la creazione di una spia per ogni funzione:

window.mock = function (constr, name) { 
    var keys = []; 
    for (var key in constr.prototype) 
    keys.push(key); 
    return keys.length > 0 ? jasmine.createSpyObj(name || "mock", keys) : {}; 
}; 

Quindi, se ho capito bene, che lui usa come questo (esempio tratto dal suo blog):

012.
var el = mock($); 
el('.some-not-existing-class').css('background', 'red'); 
expect(el.css).toHaveBeenCalledWith('background', 'red'); 

Tuttavia, questo non funziona, dal momento che è un elobject e non un function.

Il mio approccio per risolvere questo problema: ho refactoring sua funzione mock per spiegare il caso che constr è un function:

mock (constr, name) { 
    var keys = []; 
    for (var key in constr.prototype) 
    keys.push(key); 
    var result = keys.length > 0 ? jasmine.createSpyObj(name || "mock", keys) : {}; 

    // make sure that if constr is a function (like in the case of jQuery), the mock is too 
    if (typeof constr === 'function') { 
    var result2 = result; 
    result = jasmine.createSpy(name || 'mock-fn'); 
    for (var key in result2) 
     result[key] = result2[key]; 
    } 
    return result; 
} 

Tuttavia, la seconda linea nel test lancia un errore Cannot read property css of undefined:

var el = mock($); 
el('.some-not-existing-class').css('background', 'red'); 
expect(el.css).toHaveBeenCalledWith('background', 'red'); 

Altre idee: ho anche cercato di fondere l'oggetto di spionaggio i nto jQuery, ma non è stato d'aiuto.

Qualche idea? Spero che non siamo gli unici a farlo senza dispositivi HTML.

risposta

0

Trovato. Quando la mia versione della funzione mock è impostato per restituire l'oggetto jQuery quando viene richiamata la funzione jQuery, il test funziona:

mock (constr, name) { 
    var keys = []; 
    for (var key in constr.prototype) 
    keys.push(key); 
    var result = keys.length > 0 ? jasmine.createSpyObj(name || "mock", keys) : {}; 

    // make sure that if constr is a function (like in the case of jQuery), the mock is too 
    if (typeof constr === 'function') { 
    var result2 = result; 
    result = jasmine.createSpy(name || 'mock-fn'); 
    result.and.returnValue(result); 
    for (var key in result2) 
     result[key] = result2[key]; 
    } 
    return result; 
} 
0

È possibile utilizzare sinon.js stubs anziché utilizzare i propri metodi di supporto.

stub = sinon.stub(jQuery.fn, 'css'); 

// invoke code which calls the stubbed function 

expect(stub.calledWith({ 'background': 'red' })).toBe(true); 
stub.restore(); 
+0

provato che con la linea '$ ('abc') css ('background'. , 'rosso'); 'come codice di prova. Tuttavia, l'assert fallisce, 'sub.calledWith' restituisce false. – cheeesus