使用 testdoublejs 测试具有多个 then 的 Promise
Testing Promises with multiple thens using testdoublejs
我正在使用 testdouble
在我的 node.js 项目中存根调用。这个特定的函数正在包装一个承诺,并且在函数本身内有多个 then
调用。
function getUser (rethink, username) {
return new Promise((resolve, reject) => {
let r = database.connect();
r.then(conn => database.table(tablename).filter({username}))
.then(data => resolve(data))
.error(err => reject(err));
});
}
所以我想根据错误情况确定 resolve
和 reject
是否被正确处理。假设我需要验证其中的一些自定义逻辑。
为了我的测试
import getUser from './user';
import td from 'testdouble';
test(t => {
const db = td.object();
const connect = td.function();
td.when(connect('options')).thenResolve();
const result = getUser(db, 'testuser');
t.verify(result);
}
问题是 connect 的结果需要是一个承诺,所以我使用 then resolve 的值需要是另一个解决或拒绝的承诺。
它相关的行是 database.connect()
的结果,不是承诺。
TypeError: Cannot read property 'then' of undefined
有人成功地用 Test Double 对这种类型的调用进行了 stub 处理吗?
测试替身为单元测试提供存根。在您的情况下 'db' 是我们需要模拟的对象。通过
创建模拟数据库
td.object(Database) // Database is the class or constructor of your db
将是正确的选择,但如果只是模拟您在这种情况下需要的那些方法,我不会选择那种方式。
这是测试模块,'some.js':
function getUser (database, username) {
return new Promise((resolve, reject) => {
let r = database.connect();
r.then(conn => database.table('table').filter({username:username}))
.then(data => resolve(data))
.catch(err => reject(err));
});
}
module.exports = getUser;
和测试文件,使用 mocha 和 chai.expect,也可以是这里的任何其他单元测试模块:
let td = require('testdouble');
let expect = require('chai').expect;
const getUser = require('./some');
describe('some.js',()=>{
it('getUser',()=>{
const db = {};
const name = 'name';
db.connect = td.function();
db.table = td.function('table');
db.filter = td.function('filter');
td.when(db.connect()).thenResolve(db);
td.when(db.table('table')).thenReturn(db);
td.when(db.filter({username: name})).thenResolve('some user data');
return getUser(db, name)
.then(user=>{
expect(user).to.equal('some user data')
})
.catch(e=>assert(e))
})
})
因此,如果您对这些内容感到困惑,请告诉我。
所以想出了解决办法。解决方案中有几点需要注意,也是我们遇到的。简而言之,最终的决议是这样的...
td.when(database.connect()).thenResolve({then: (resolve) => resolve('ok')});
这解决了当测试替身看到数据库连接时返回的 thenable。然后后面的调用也可以加上。
还有一个部分需要注意,如果您将对象发送到 database.connect()
,您必须知道它正在进行 ===
相等性检查,并且您需要引用该对象正确使用 td.when
.
的对象
我正在使用 testdouble
在我的 node.js 项目中存根调用。这个特定的函数正在包装一个承诺,并且在函数本身内有多个 then
调用。
function getUser (rethink, username) {
return new Promise((resolve, reject) => {
let r = database.connect();
r.then(conn => database.table(tablename).filter({username}))
.then(data => resolve(data))
.error(err => reject(err));
});
}
所以我想根据错误情况确定 resolve
和 reject
是否被正确处理。假设我需要验证其中的一些自定义逻辑。
为了我的测试
import getUser from './user';
import td from 'testdouble';
test(t => {
const db = td.object();
const connect = td.function();
td.when(connect('options')).thenResolve();
const result = getUser(db, 'testuser');
t.verify(result);
}
问题是 connect 的结果需要是一个承诺,所以我使用 then resolve 的值需要是另一个解决或拒绝的承诺。
它相关的行是 database.connect()
的结果,不是承诺。
TypeError: Cannot read property 'then' of undefined
有人成功地用 Test Double 对这种类型的调用进行了 stub 处理吗?
测试替身为单元测试提供存根。在您的情况下 'db' 是我们需要模拟的对象。通过
创建模拟数据库td.object(Database) // Database is the class or constructor of your db
将是正确的选择,但如果只是模拟您在这种情况下需要的那些方法,我不会选择那种方式。
这是测试模块,'some.js':
function getUser (database, username) {
return new Promise((resolve, reject) => {
let r = database.connect();
r.then(conn => database.table('table').filter({username:username}))
.then(data => resolve(data))
.catch(err => reject(err));
});
}
module.exports = getUser;
和测试文件,使用 mocha 和 chai.expect,也可以是这里的任何其他单元测试模块:
let td = require('testdouble');
let expect = require('chai').expect;
const getUser = require('./some');
describe('some.js',()=>{
it('getUser',()=>{
const db = {};
const name = 'name';
db.connect = td.function();
db.table = td.function('table');
db.filter = td.function('filter');
td.when(db.connect()).thenResolve(db);
td.when(db.table('table')).thenReturn(db);
td.when(db.filter({username: name})).thenResolve('some user data');
return getUser(db, name)
.then(user=>{
expect(user).to.equal('some user data')
})
.catch(e=>assert(e))
})
})
因此,如果您对这些内容感到困惑,请告诉我。
所以想出了解决办法。解决方案中有几点需要注意,也是我们遇到的。简而言之,最终的决议是这样的...
td.when(database.connect()).thenResolve({then: (resolve) => resolve('ok')});
这解决了当测试替身看到数据库连接时返回的 thenable。然后后面的调用也可以加上。
还有一个部分需要注意,如果您将对象发送到 database.connect()
,您必须知道它正在进行 ===
相等性检查,并且您需要引用该对象正确使用 td.when
.