unit testing连接数据库的asynchronousfunction

那么我有一些函数连接到数据库(redis)并返回一些数据,这些函数通常是基于承诺,但是asynchronous和包含stream。 我看了一些关于testing的东西,我select了用磁带 ,sinon和proxyquire,如果我嘲笑这个function,我会知道它的工作原理?

以下函数(listKeys)在完成扫描后返回(通过承诺)存在于redis db中的所有密钥。

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) }) } } 

那么你如何testing这样的function呢?

我认为有几个方法通过testing来练习这个function,并且都围绕着configurationtestingstream来使用你的testing。

我喜欢编写我认为重要的testing用例,然后找出实现它们的方法。 对我来说最重要的是类似的东西

 it('should resolve cacheKeys on end') 

然后需要创build一个stream来提供给你的function

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

然后扫描stream需要由您的testing来控制

你可以通过创build一个假客户端来做到这一点

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

然后一个testing可以configuration你的断言

 var testKeys = ['t']; Method.listKeys().then((cacheKeys) => { assert(cacheKeys).toEqual(testKeys); done() }) 

现在,您的承诺正在等待您的stream断言发送数据stream。

 stream.emit('data', testKeys) 

通过模拟数据库stream,通过发送数据并检查是否正确保存,来testing密钥是否被正确保存到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');