2015-06-21 8 views
6

vortäuscht Was ich tun möchte: Wir schreiben einige Tests für eine vorhandene Javascript-Codebasis, die jQuery stark verwendet. Für die Tests wollen wir keine echten HTML-Elemente (HTML-Fixtures) haben. Wir würden es bevorzugen, wenn wir ein jQuery-Mock-Objekt hätten, das nichts mit HTML zu tun hat.Wie man jQuery mit Jasmine

Mein Ausgangspunkt: Der vielversprechendste Ansatz fand ich hier:

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

Dieses eine Hilfsmethode erstellt, die für jeden, indem Sie durch die Funktionen eines Objekts und die Schaffung eines Spion ein Mock schafft Funktion:

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) : {}; 
}; 

Dann, wenn ich ihn richtig verstanden habe, nutzt er, wie dieser (angepasst Beispiel aus seinem Blog-Post):

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

Allerdings bedeutet dies nicht, da el ist ein object und kein function.

Mein Ansatz, um dieses Problem zu beheben: ich seine mock Funktion Refactoring für den Fall zu berücksichtigen, dass constr ein function ist:

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; 
} 

Allerdings wirft die zweite Zeile in dem Test einen Cannot read property css of undefined Fehler:

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

Andere Ideen: ich habe auch versucht, den Spion Objekt zu verschmelzen i nto jQuery, aber das hat auch nicht geholfen.

Irgendwelche Ideen? Ich hoffe, wir sind nicht die einzigen, die es ohne HTML-Fixtures machen.

Antwort

0

Gefunden. Als meine Version der mock Funktion eingerichtet ist, das jQuery-Objekt zurück, wenn die jQuery-Funktion aufgerufen wird, funktioniert der Test:

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

Sie können sinon.js stubs anstelle Ihrer eigenen Hilfsmethoden verwenden.

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

// invoke code which calls the stubbed function 

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

versucht, dass mit der Linie '$ (‚abc‘) css (‚Hintergrund‘. , 'rot'); 'als Testcode. Die Assertion schlägt jedoch fehl, "sub.calledWith" gibt false zurück. – cheeesus