2011-05-12 94 views
0

漸進地做這件事的最好方法是什麼?例如,一些網址必須在別人之前訪問才能填充數據庫等。是否有單元測試的慣用節點方式?Nodejs單元測試網址

我目前從json文件中讀取單元測試數據,然後根據這個請求讀取單元測試數據。

function urlTestFn(test){ 
    var req = requestProperties(test); 
    var request = http.request(req, function(resp) { 
     resp.setEncoding('utf8'); 
     resp.on('data',function(data) { 
      if(data == JSON.stringify(test.response)) { 
       //success 
      } else { 
       sys.puts('fail'); 
      } 
     }); 
    }); 
    if(req.method == 'POST'){ 
     request.write(JSON.stringify(test.postData)); 
    } 
    request.end(); 
} 

回答

1

確定,一些提示。你的代碼似乎沒有使用任何測試框架,所以至少應該使用commonJS斷言或測試框架。我更喜歡jasmine,但有幾個好的。茉莉花對間諜和異步測試有很大的支持。作爲一個方面的評論,這些不是單元測試,根據定義它不會觸及數據庫,這些測試最有可能是應用程序/系統測試。除了這些通過整個堆棧發送實時數據的系統級測試之外,您可能還想考慮爲您的服務器端代碼編寫一些純粹的單元測試。

關於測試先決條件的主題,通常儘量使每個測試儘可能獨立。但是,當完全獨立性不可避免時,大多數單元測試框架都有一個概念,即在每次測試之前和之後調用的一對函數。在jasmine中,這是beforeEach函數。將DB對象預加載爲「fixtures」有時在Rails社區中完成。還有「工廠」的概念。每個戰略都有優勢和缺點。我不確定是否有工廠或燈具的節點庫,但要進行網絡搜索。

2

要增加Peter Lynos的建議,請允許我向您介紹單元測試的正確思路。在進行單元測試時,很多人會問錯誤的問題。這不是「我該如何測試」,而是「我要測試什麼」。在你的情況下,你想測試你的代碼,邏輯,而不是別的。這意味着您必須刪除所有外部因素,包括第三方庫,npm模塊,甚至是node.js核心API模塊。

問問你自己:你可以複製你的測試套件並運行它,而無需花費幾個小時來設置環境?你應該能夠。這就是編寫單元測試的重點 - 使其單獨運行以確保代碼正確。我們稱之爲「環境」,您的代碼可以獨立於「控制環境」運行,類似於科學界使用的相同術語。

現在要實現這一點,您需要了解燈具和嘲笑的概念。有燈具可以創造你的控制環境。它通過創建一堆模擬對象來實現,其中每個模擬對象接受輸入並生成輸出。通過這種方式,您可以精確控制代碼的各個方面,並且使測試從DB操作到REST請求的各種東西變得非常簡單。

最後,在理解的是:

  1. 最好測試套件是一個可以在一個孤立的,控制環境
  2. 夾具被用來創建該環境通過提供您的代碼與模擬對象
  3. 運行
  4. 模擬對象需要輸入並返回輸出
  5. 以上三件事情只有在您已經用100%注入依賴項編碼項目時才能實現

mock對象

假設在你的函數foo()要讀取文件的內容,這裏是你的模擬看起來應該像:

var FsMock = { 
    readFile : function readFile(path, encoding, callback) { 
     if (path === 'unit-test-1') 
      callback(null, 'This is the file contents'); 
     else 
      callback(new Error('Unexpected error'); 
    } 
} 

,然後在測試代碼,你嘗試讀取文件'unit-test-1',它將返回'這是文件內容'。

依賴注入

上述所有的是,如果你的項目沒有寫他們之間的依賴外部注入極其困難。現在我的約定是所有模塊都必須有一個make()函數,它接受一個包含所有依賴關係的對象。這裏有一個簡單的例子:

var Fs = null; 
var Path = null; 

var TestObj = module.exports = { 
    make : function make(args) { 
     if ('undefined' === typeof args.fs) 
      throw new Error('Dependency: FS module needed'); 
     if ('undefined' === typeof args.path) 
      throw new Error('Dependency: Path module needed'); 

     Fs = args.fs; 
     Path = args.fs; 

     return Object.create(this); 
    } 
} 

然後你需要一個工廠或DI容器爲你的對象構建它,自動構造它的依賴關係。

只有這樣,BDD和TDD纔會在您的項目中變得有趣。希望這可以幫助!