2012-03-05 28 views
6

Tôi đang đấu tranh để viết các bài kiểm tra chất lượng cao xung quanh các mô-đun nút của tôi. Vấn đề là hệ thống mô-đun yêu cầu. Tôi muốn có thể kiểm tra xem một mô-đun cần thiết nào đó có một phương thức hay trạng thái của nó đã thay đổi. Dường như có 2 thư viện tương đối nhỏ có thể được sử dụng tại đây: node-gentlymockery. Tuy nhiên, do 'hồ sơ' thấp của họ khiến tôi nghĩ rằng một trong hai người không thử nghiệm điều này, hoặc có một cách khác để làm điều này mà tôi không biết.Kiểm tra Node.js, thử và thử nghiệm một mô-đun đã được yêu cầu?

Cách tốt nhất để thử và thử nghiệm một mô-đun đã được yêu cầu là gì?

Trả lời

10

----------- CẬP NHẬT ---------------

node-sandbox công trình trên gốc giống như được nêu dưới đây nhưng được bao bọc trong một mô-đun đẹp. Tôi thấy rất tuyệt khi làm việc cùng.


--------------- awnser chi tiết ---------------

Sau nhiều thử nghiệm Tôi có tìm thấy cách tốt nhất để kiểm tra các mô-đun nút trong sự cô lập trong khi chế nhạo mọi thứ là sử dụng phương pháp của Vojta Jina để chạy từng mô-đun bên trong vm với ngữ cảnh mới như được giải thích here.

với module vm thử nghiệm này:

var vm = require('vm'); 
var fs = require('fs'); 
var path = require('path'); 

/** 
* Helper for unit testing: 
* - load module with mocked dependencies 
* - allow accessing private state of the module 
* 
* @param {string} filePath Absolute path to module (file to load) 
* @param {Object=} mocks Hash of mocked dependencies 
*/ 
exports.loadModule = function(filePath, mocks) { 
    mocks = mocks || {}; 

    // this is necessary to allow relative path modules within loaded file 
    // i.e. requiring ./some inside file /a/b.js needs to be resolved to /a/some 
    var resolveModule = function(module) { 
    if (module.charAt(0) !== '.') return module; 
    return path.resolve(path.dirname(filePath), module); 
    }; 

    var exports = {}; 
    var context = { 
    require: function(name) { 
     return mocks[name] || require(resolveModule(name)); 
    }, 
    console: console, 
    exports: exports, 
    module: { 
     exports: exports 
    } 
    }; 

    vm.runInNewContext(fs.readFileSync(filePath), context); 
    return context; 
}; 

người ta có thể kiểm tra mỗi mô-đun với bối cảnh riêng của mình và dễ dàng còn sơ khai ra tất cả dependencys bên ngoài.

fsMock = mocks.createFs(); 
mockRequest = mocks.createRequest(); 
mockResponse = mocks.createResponse(); 

// load the module with mock fs instead of real fs 
// publish all the private state as an object 
module = loadModule('./web-server.js', {fs: fsMock}); 

Tôi đặc biệt khuyên bạn nên viết các bài kiểm tra hiệu quả một cách độc lập. Chỉ các bài kiểm tra chấp nhận mới có thể đạt được toàn bộ ngăn xếp. Các bài kiểm tra đơn vị và tích hợp nên kiểm tra các phần riêng biệt của hệ thống.

+0

Cảm ơn câu trả lời tuyệt vời! Tuy nhiên tôi có một câu hỏi khác: Tôi đã không thể tận dụng kỹ thuật này để ghi đè các chức năng riêng tư bằng các chức năng tùy chỉnh của riêng tôi trong mô-đun đang được thử nghiệm. nó kết quả trong hai chức năng: một trong phạm vi địa phương và một trong phạm vi toàn cầu, với các mô-đun được kiểm tra luôn gọi phiên bản toàn cầu/bản gốc. – Attilah

5

Tôi nghĩ rằng mô hình nhạo báng là một mô hình tốt. Điều đó nói rằng, tôi thường chọn gửi phụ thuộc như các tham số cho một hàm (tương tự như truyền các phụ thuộc trong hàm dựng).

// foo.js 
module.exports = function(dep1, dep2) { 
    return { 
     bar: function() { 
      // A function doing stuff with dep1 and dep2 
     } 
    } 
} 

Khi thử nghiệm, tôi có thể gửi mocks, đối tượng trống để thay thế, bất cứ điều gì có vẻ phù hợp. Lưu ý rằng tôi không làm điều này cho tất cả các phụ thuộc, về cơ bản chỉ IO - Tôi không cảm thấy cần phải kiểm tra mã của tôi gọi path.join hoặc bất cứ điều gì.

Tôi nghĩ rằng "cấu hình thấp" đó là làm cho bạn lo lắng là do một vài điều:

  • Một số người cấu trúc mã của họ tương tự như khai thác
  • Một số người có helper của mình thực hiện cùng mục tiêu như mockery et al (đó là một mô-đun rất đơn giản)
  • Một số người không đơn vị kiểm tra những thứ như vậy, thay vì quay lên một ví dụ của ứng dụng của họ (và db, vv) và thử nghiệm chống lại điều đó. Kiểm thử sạch hơn và máy chủ quá nhanh, nó không ảnh hưởng đến hiệu suất thử nghiệm.

Tóm lại, nếu bạn cho rằng sự nhạo báng phù hợp với mình, hãy thực hiện nó!

+0

Vấn đề với điều này là các đơn vị kiểm tra là đánh cơ sở dữ liệu mà không phải là lý tưởng. –

+1

@beck: Chỉ khi bạn gửi một db thực khi kiểm tra. –

1

Quý khách dễ dàng thử yêu cầu bằng cách sử dụng "a": https://npmjs.org/package/a

//Example faking require('./foo') in unit test: 
var fakeFoo = {}; 
var expectRequire = require('a').expectRequire; 
expectRequire('./foo).return(fakeFoo); 


//in sut: 
var foo = require('./foo); //returns fakeFoo 
Các vấn đề liên quan