[英]Unit testing asynchronous function which connects to database
我有一些连接到数据库(redis)并返回一些数据的函数,这些函数通常基于promises但是是异步的并且包含流。 我查看并阅读了一些关于测试的内容,我选择使用磁带 ,sinon和proxyquire,如果我嘲笑这个函数我怎么知道它有效?
以下函数(listKeys)在完成扫描后返回(通过promise)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)
})
}
}
那么你如何测试这样的功能呢?
我认为有几种方法可以通过测试来执行此功能,并且所有方法都围绕配置测试使用的测试流。
我喜欢编写我认为最重要的测试用例,然后找出实现它们的方法。 对我来说最重要的是像
it('should resolve cacheKeys on end')
然后需要创建一个流来提供您的功能
var Stream = require('stream');
var stream = new Stream();
然后扫描流需要由您的测试控制
你可以通过创建一个假客户端来做到这一点
client = {
scanStream: (config) => { return stream }
}
然后可以使用您的断言配置测试
var testKeys = ['t'];
Method.listKeys().then((cacheKeys) => {
assert(cacheKeys).toEqual(testKeys);
done()
})
现在您的承诺正在等待您的流,并使用断言将数据发送到流。
stream.emit('data', testKeys)
一种简单的方法,通过模拟数据库流,在其上发送数据并检查是否正确保存,来测试密钥是否正确保存到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');
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.