2016-01-31 58 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');