2015-06-21 26 views
6

Những gì tôi muốn làm: Chúng tôi đang viết một số kiểm tra cho một cơ sở mã Javascript hiện có sử dụng jQuery rất nhiều. Đối với các bài kiểm tra, chúng tôi không muốn có các phần tử HTML thực tế (các đồ đạc HTML). Chúng tôi muốn nó nếu chúng tôi có một đối tượng giả lập jQuery mà không làm bất cứ điều gì liên quan đến HTML.Làm thế nào để giả lập jQuery với Jasmine

điểm khởi đầu của tôi: Cách tiếp cận đầy hứa hẹn nhất mà tôi tìm thấy ở đây:

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

Điều này tạo ra một phương pháp helper tạo ra một mô hình bằng cách đi qua các chức năng của một đối tượng và tạo ra một gián điệp cho mỗi chức năng:

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

sau đó, nếu tôi hiểu anh ta một cách chính xác, ông sử dụng đó như thế này (ví dụ chuyển thể từ bài viết trên blog của mình):

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

Tuy nhiên, điều này không hoạt động, vì elobject và không phải là function.

Biện pháp của tôi để giải quyết vấn đề này: tôi refactored chức năng mock mình vào tài khoản cho trường hợp đó constr là một 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; 
} 

Tuy nhiên, dòng thứ hai trong các thử nghiệm ném một lỗi Cannot read property css of undefined:

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

Ý tưởng khác: Tôi cũng đã cố hợp nhất đối tượng gián điệp i jQuery, nhưng điều đó cũng không giúp được gì.

Bất kỳ ý tưởng nào? Tôi hy vọng chúng tôi không phải là những người duy nhất làm điều đó mà không có đồ đạc HTML.

Trả lời

0

Tìm thấy. Khi phiên bản của tôi về mock chức năng được thiết lập để trả lại đối tượng jQuery khi hàm jQuery được gọi, kiểm tra hoạt động:

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

Bạn có thể sử dụng sinon.js stubs, thay vì lăn phương thức trợ giúp của riêng bạn.

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

// invoke code which calls the stubbed function 

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

Cố gắng rằng với dòng '$ ('abc') css ('nền'. , 'red'); 'làm mã kiểm tra. Tuy nhiên, xác nhận không thành công, 'sub.calledWith' trả về false. – cheeesus

Các vấn đề liên quan