2012-10-10 6 views
12

Tôi đã tạo một trình bao bọc cơ sở dữ liệu cho ứng dụng của mình, được hiển thị bên dưới. Để kiểm tra nó, tôi rõ ràng muốn thay thế thư viện cơ sở dữ liệu thực tế. Tôi có thể tạo ra một lớp mới mà mocks phương pháp query và bắt tất cả các đầu vào có, nhưng sử dụng sinon.js có vẻ thích hợp hơn, nhưng làm thế nào tôi sẽ sử dụng nó?
Các tính năng mock hoặc stub của sinon.js những gì tôi nên sử dụng?Kéo và/hoặc chế nhạo một lớp trong sinon.js?

wrapper = (function() { 

    function wrapper() {} 

    wrapper.db = require("database"); 

    wrapper.prototype.insertUser = function(doc) { 
    return this.db.query("INSERT INTO USERS..."); 
    }; 

    return wrapper; 

})(); 

Trả lời

6

Bạn có thể sử dụng cả hai cho điều đó.

Mock có hành vi được yêu cầu theo thứ tự mong đợi, nếu không được theo dõi chính xác, sẽ cho bạn lỗi.

A Stub tương tự như mô hình, nhưng không có thứ tự, vì vậy bạn có thể gọi các phương pháp theo cách bạn muốn. Theo kinh nghiệm của tôi, bạn hầu như không bao giờ cần một mô hình.

Cả hai người trong số họ sẽ thay thế phương pháp của bạn cho một phương thức trống hoặc đóng cửa nếu bạn vượt qua một phương pháp. Nó sẽ giống như sau:

stub = sinon.stub(wrapper , 'insertUser ', function() { return true; }); 

Sau đó, bạn thêm hành vi mong đợi để kiểm tra xem nó có xảy ra không.

Tôi thích sử dụng Jasmine với Jasmine-Sinon để kiểm tra các thử nghiệm.

+0

Ồ. Vì vậy, tốt hơn là nên sử dụng phương thức 'insertUser' thay vì lệnh' this.db' mà 'insertUser' thực hiện? – Industrial

+2

Phụ thuộc vào những gì bạn đang thử nghiệm, nhưng nếu bạn muốn kiểm tra xem trình chèn thêm có đang chèn vào DB mà sẽ là một phép thử tích hợp và không bị lúng túng sẽ giúp bạn tiết kiệm từ việc sử dụng logic thực với một số trong bộ nhớ DB. ví dụ, nếu bạn muốn kiểm tra nếu trình insertUser được gọi khi cần thì phương thức insertUser có thể là một cách để làm ... –

8

Trước tiên, tôi muốn thay đổi định nghĩa lớp học của bạn một chút (tên lớp chữ hoa và sửa chữa db phân công):

var Wrapper = (function() { 

    function Wrapper() { 
    this.db = require("database"); 
    } 

    Wrapper.prototype.insertUser = function(doc) { 
    return this.db.query("INSERT INTO USERS..."); 
    }; 

    return Wrapper; 

})(); 

Để còn sơ khai cả lớp:

var WrapperStub = sinon.spy(function() { 
    return sinon.createStubInstance(Wrapper); 
}); 

sinon.createStubInstance sẽ tạo ra một thể hiện của Wrapper, nơi mọi phương thức đều là sơ khai. sinon.spy sẽ cho phép chúng tôi theo dõi lớp học.

Vì vậy, bạn có thể thực hiện nó như thế này:

// verify instantiation 
var wrapper = new WrapperStub(); 
expect(WrapperStub).to.have.been.calledWithNew; 

// verify method stub 
wrapper.insertUser.returns('data'); 
expect(wrapper.insertUser()).to.equal('data'); 
expect(wrapper.insertUser).to.have.been.calledOnce; 

(khẳng định sử dụng chaisinon-chai)

tôi đã nói chỉ là "tập thể dục nó" vì đoạn mã này không phải là một bài kiểm tra đơn vị thực tế. Các cuộc gọi và các cuộc gọi phương thức sẽ được thực hiện bởi chủ thể của bạn đang được kiểm tra.

Bây giờ, nếu bạn muốn thử một sự phụ thuộc tiêm bởi require() -such như db = require('database') trong example- của bạn, bạn có thể thử một công cụ kiểm tra như một trong hai Jest (nhưng không sử dụng Sinon) hoặc sinonquire mà tôi tạo ra cảm hứng của Jest nhưng để sử dụng nó với sinon cộng với công cụ kiểm tra yêu thích của bạn (mỏ là mocha). Bên trong, sinonquire sử dụng cùng một kỹ thuật được hiển thị ở trên kết hợp sinon.spysinon.createStubInstance để phân phát một lớp.

+0

Cập nhật các liên kết tới Jest: https://facebook.github.io/jest/docs/mock -functions.html http://facebook.github.io/jest/docs/jest-object.html#jestenableautomock – jwadsack