2015-06-21 16 views
6

Что я хочу делать: Мы пишем несколько тестов для существующей базы кода JavaScript, которая сильно использует jQuery. Для тестов мы не хотим иметь фактические HTML-элементы (HTML-светильники). Мы предпочли бы, если бы у нас был jQuery mock object, который не делает ничего связанного с HTML.Как издеваться над jQuery с Jasmine

Моя точка: Наиболее перспективный подхода я нашел здесь:

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

Это создает вспомогательный метод, который создает макет, перейдя через функцию объекта и создание шпиона для каждого функция:

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

Тогда, если я понимаю его правильно, он использует это как это (адаптированный пример из его блога):

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

Однако, это не работает, так как el является object и не function.

Мой подход для решения этой проблемы: Я переработан его mock функцию, чтобы объяснить для случая, когда constr является 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; 
} 

Однако вторая линия в тесте бросает ошибку Cannot read property css of undefined:

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

Другие идеи: я также пытался объединить объект шпионской я nto jQuery, но это тоже не помогло.

Любые идеи? Надеюсь, мы не единственные, кто делает это без HTML-светильников.

ответ

0

Обнаружено. Когда моя версия функции mock настроена вернуть объект JQuery, когда функция JQuery вызывается, тест работы:

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

Вы можете использовать sinon.js stubs, вместо того, чтобы катать свои собственные вспомогательные методы.

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

// invoke code which calls the stubbed function 

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

Пробовал, что с линией '$ («ABC») CSS («фон». , 'red'), 'как тестовый код. Однако утверждение не выполняется, 'sub.calledWith' возвращает false. – cheeesus

Смежные вопросы