Тестирование Promises с несколькими thens с помощью 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);
}
Проблема в том, что результат подключения должен быть обещанием, поэтому я использую затем решение со значением, которое должно быть другим обещанием, которое разрешает или отклоняет.
Линия, к которой он относится, является результатом database.connect()
не является обещанием.
TypeError: Cannot read property 'then' of undefined
У кого-то есть успех с завершением этого типа вызова с помощью Test Double?
Ответы
Ответ 1
Так понял решение. В решении есть несколько замечаний, с которыми мы столкнулись. Короче, резолюция оказалась в этом...
td.when(database.connect()).thenResolve({then: (resolve) => resolve('ok')});
Это разрешает затемствуемое, которое возвращается, когда тестовое двойное соединение соединяется с базой данных. Затем могут быть добавлены последующие вызовы.
Также есть часть, чтобы отметить, если вы отправляете объект в database.connect()
, вам нужно знать, что он выполняет проверку равенства ===
, и вам нужно будет иметь ссылку на этот объект, чтобы он правильно использовал td.when
.
Ответ 2
Test double предоставляет заглушки для модульного тестирования. И в вашем случае "db" - это объект, который нам нужно высмеять. Создание дразнящего 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, который также может быть любым другим unit test модулем здесь:
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))
})
})
Поэтому, пожалуйста, дайте мне знать, если кто-то из вас смущает вас.