2017-02-17 27 views
0

我正在嘗試爲以下函數編寫測試。使用Mocha.js測試預定義的回調函數

function services(api){ 
    request(`${api}?action=services`, function(err, res, body) { 
     if (!err && res.statusCode === 200){ 
      var resJson = JSON.parse(body); 
      var numberOfServices = resJson.length; 
      console.log("Service called: services"); 
      console.log("-----------"); 
      for (i = 0; i < numberOfServices; i++){ 
       console.log("Service ID: " + resJson[i].service); 
       console.log("Service Name: " + resJson[i].name); 
       console.log("-----------"); 
      } 
      return resJson; 
     } 
    }); 
} 

測試正在檢查函數是否返回對象。 resJson是要返回並測試的對象。

下面是使用Mocha.js和Chai.js聲明庫編寫的測試用例。

var chai = require('chai'); 
var assert = chai.assert; 
var sendRequest = require('../request'); 

describe('Test 1', function() { 

    var api = 'http://instant-fans.com/api/v2'; 

    it('services() should return an object of services', function(done) { 
     var object = sendRequest.services(api); 
     assert.isObject(object); 
    }); 

}); 

但是,當我運行測試時失敗,出現以下控制檯輸出。說resJson是未定義的。我猜測,摩卡正試圖斷言resJson是一個對象之前函數services()返回對象,但我不知道如何解決這個問題。

Test 1 
    1) services() should return an object of services 

0 passing (27ms) 
1 failing 

    1) Test 1 services() should return an object of services: 
    AssertionError: expected undefined to be an object 
     at Function.assert.isObject (node_modules/chai/lib/chai/interface/assert.js:555:35) 
     at Context.<anonymous> (test/requestTest.js:11:16) 

我曾嘗試這種在網上搜索,我看到人們解決這個使用done()方法。但在我的情況下,這是行不通的,因爲我在services()函數中使用了回調。

回答

0

我建議你閱讀的異步函數


question關於使用您不能分配異步函數調用變量就像在var object = sendRequest.services(api)做。您需要使用callback,應添加作爲一個參數services功能

function services(api, callback){ 
    // your logic here 
} 

,而是執行return resJson你可以調用callback(resJson)services功能。然後,在您的測試,你需要調用services與第二個參數是一個function(result)

sendRequest.services(api, function(result){ 
    assert.isObject(result); 
}); 

編輯

這是你的services功能看起來應該像

function services(api, callback){ 
    request(`${api}?action=services`, function(err, res, body) { 
     if (!err && res.statusCode === 200){ 
      var resJson = JSON.parse(body); 
      var numberOfServices = resJson.length; 
      console.log("Service called: services"); 
      console.log("-----------"); 
      for (i = 0; i < numberOfServices; i++){ 
       console.log("Service ID: " + resJson[i].service); 
       console.log("Service Name: " + resJson[i].name); 
       console.log("-----------"); 
      } 
      callback(resJson); 
     } 
    }); 
} 
+0

我是否將需要進行更改'服務()'函數? –

+0

是的,正如我所說的,而不是做'返回resJson'你應該做'回調(resJson)'。這將確保您完成斷言。我編輯的答案與更新'services'功能 – piotrbienias

+0

啊那是我第一次遇到的是,謝謝,你! :) –

0

您的代碼看起來像是在做異步請求sendRequest.services(api);

你需要做的是處理done()回調在摩卡測試提供:it('services() should return an object of services', function(done) {})

你需要做的是什麼重新寫你的services功能,因爲它是不正確。您不能從異步函數返回,異步函數通常是基於I/O的,並且不會阻塞主Nodejs線程。爲了讓你的主線程訪問你必須傳入的回調函數的值,一旦該值可用,將執行該回調函數。

function services(api, cb){ 
    request(`${api}?action=services`, function(err, res, body) { 
     var resJson; 
     if (!err && res.statusCode === 200){ 
      resJson = JSON.parse(body); 
      var numberOfServices = resJson.length; 
      console.log("Service called: services"); 
      console.log("-----------"); 
      for (i = 0; i < numberOfServices; i++){ 
       console.log("Service ID: " + resJson[i].service); 
       console.log("Service Name: " + resJson[i].name); 
       console.log("-----------"); 
      } 
     } 
     if (cb) { 
      cb(err, resJson); 
     } 
    }); 
} 

和重寫你的測試,像這樣:

describe('Test 1', function() { 
    var api = 'http://instant-fans.com/api/v2'; 

    it('services() should return an object of services', function(done) { 
     sendRequest.services(api, function(resJson) { 
      assert.isObject(resJson); 
      done(); 
     }); 
    }); 

}); 

我會再進一步​​,通過在錯誤的回調函數(這是的NodeJS常見的做法):

cb(err, resJson); 

而且你的測試可以打印錯誤更好的調試:

sendRequest.services(api, function(err, resJson) { 
    if (err) { 
     console.error(err); 
    } 
    assert.isObject(resJson); 
    done(); 
}); 
相關問題