2016-01-31 101 views
1

那麼我有一些連接到數據庫(redis)並返回一些數據的函數,這些函數通常是基於promises但是是異步的並且包含流。我查閱了一些關於測試的內容,並且選擇了tape,sinon和proxyquire,如果我嘲笑這個函數,我會如何知道它的工作原理?連接數據庫的單元測試異步功能

以下函數(listKeys)在完成掃描後返回(通過承諾)存在於redis數據庫中的所有密鑰。

let methods = { 
    client: client, 
    // Cache for listKeys 
    cacheKeys: [], 
    // Increment and return through promise all keys 
    // store to cacheKeys; 
    listKeys: blob => { 
     return new Promise((resolve, reject) => { 
      blob = blob ? blob : '*'; 

      let stream = methods.client.scanStream({ 
       match: blob, 
       count: 10, 
      }) 

      stream.on('data', keys => { 
       for (var i = 0; i < keys.length; i++) { 
        if (methods.cacheKeys.indexOf(keys[i]) === -1) { 
         methods.cacheKeys.push(keys[i]) 
        } 
       } 
      }) 

      stream.on('end',() => { 
       resolve(methods.cacheKeys) 
      }) 

      stream.on('error', reject) 
     }) 
    } 
} 

那麼,你如何測試這樣的功能?

+0

https://github.com/WhoopInc/supertest-as-promised? –

回答

2

我認爲有幾個方法通過測試來鍛鍊這個功能,並且都圍繞配置一個測試流以供您的測試使用。

我喜歡編寫我認爲重要的測試用例,然後找出實現它們的方法。對我來說,最重要的是一樣的東西

it('should resolve cacheKeys on end') 

然後流需要創建提供給您的功能

var Stream = require('stream'); 
var stream = new Stream(); 

然後掃描流需要通過測試來控制

你可以通過創建假客戶端來做到這一點

client = { 
    scanStream: (config) => { return stream } 
} 

然後可以配置一個測試^ h的斷言現在

var testKeys = ['t']; 

Method.listKeys().then((cacheKeys) => { 

    assert(cacheKeys).toEqual(testKeys); 
    done() 
}) 

你的諾言正在等待您的流與斷言 發送數據流。

stream.emit('data', testKeys) 
1

一個簡單的方法來測試正常通過嘲諷DB流,在它發送數據,並檢查其是否得到了妥善保存密鑰是否得到保存到cacheKeys。例如:

// Create a mock stream to substitute database 
var mockStream = new require('stream').Readable(); 

// Create a mock client.scanStream that returns the mocked stream 
var client = { 
    scanStream: function() { 
     return mockStream; 
    } 
}; 

// Assign the mocks to methods 
methods.client = client; 

// Call listKeys(), so the streams get prepared and the promise awaits resolution 
methods.listKeys() 
    .then(function (r) { 
     // Setup asserts for correct results here 
     console.log('Promise resolved with: ', r); 
    }); 

// Send test data over the mocked stream 
mockStream.emit('data', 'hello'); 

// End the stream to resolve the promise and execute the asserts 
mockStream.emit('end');