Я пытаюсь протестировать свой api с помощью Jest. Мне нужно больше абстракции, поэтому я создал эту функцию:
const tokensConfig = config.get('test.tokens');
function testIt(method = 'get', url = '/', statuses = [], body = {}) {
const testNames = ['unauthorized', 'user', 'admin'];
const tokens = [null, tokensConfig.user, tokensConfig.admin];
for (let i = 0; i < testNames.length; i++) {
test(testNames[i], async () => {
const response = await request(app)
[method](url)
.set('Accept', 'application/json')
.set('Authorization', tokens[i])
.send(body);
expect(response.statusCode).toBe(statuses[i]);
});
}
}В файле test.js я запускаю:
const config = require('config');
const request = require('supertest');
const testIt = require('./testIt');
const app = require('../app');
// It's work
describe('get user by email', () => {
testIt('get', '/users/get-by-email/user@test', [401, 403, 200]);
});
// It's not work
describe('delete user', async () => {
const userByEmail = await request(app)
.get('/users/get-by-email/user@test')
.set('Accept', 'application/json')
.set('Authorization', config.get('test.tokens.admin'));
testIt('delete', `/users/${userByEmail._id}`, [401, 403, 200]);
});Проблема с async / await - testIt выполняется перед запросом пользователя.
Если я перенесу тест (или его) для описания блока из функции testIt и создаю пользователя запроса внутри теста, он будет работать. Но я хочу больше абстракции (тестовый блок очень большой для многих тестов)
Как это исправить?
Я не думаю, что describe поддерживает асинхронные функции.
@Bergi хороший улов, вот и все. describe описывает набор тестов с it.
Я понимаю, что описание не поддерживает async / await. Если я перенесу тест (или его) для описания блока из функции testIt, он будет работать. Но мне нужно больше абстракции (тестовый блок очень большой для многих тестов).



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Похоже, вам нужно сообщить в шутку, что ожидание - это асинхронный метод с resolves.
Вот пример кода из документации Jest:
// async/await can be used.
it('works with async/await', async () => {
expect.assertions(1);
const data = await user.getUserName(4);
expect(data).toEqual('Mark');
});
// async/await can also be used with `.resolves`.
it('works with async/await and resolves', async () => {
expect.assertions(1);
await expect(user.getUserName(5)).resolves.toEqual('Paul');
});
https://facebook.github.io/jest/docs/en/tutorial-async.html#async-await
В результате мне пришлось переместить контрольная работа в test.js:
// test.js
it('delete user', async () => {
const userByEmail = await request(app)
.get('/users/get-by-email/user@test')
.set('Accept', 'application/json')
.set('Authorization', config.get('test.tokens.admin'));
const result = await testIt('delete', `/users/${userByEmail.body._id}`);
expect(result).toEqual([401, 403, 401, 200]);
});// testIt.js
const config = require('config');
const request = require('supertest');
const app = require('../app');
const tokensConfig = config.get('test.tokens');
async function testIt(method = 'get', url = '/', body = {}) {
const testNames = ['unauthorized', 'user', 'adminTokenExpired', 'admin'];
const tokens = [null, tokensConfig.userTokenInfinity, tokensConfig.adminTokenExpired, tokensConfig.adminTokenInfinity];
let result = [];
for (let i = 0; i < testNames.length; i++) {
const response = await request(app)
[method](url)
.set('Accept', 'application/json')
.set('Authorization', tokens[i])
.send(body);
result.push(response.statusCode);
}
return result;
}
module.exports = testIt;Но мне пришлось ограничиться одним ответом на все роли вместо индивидуального ответа на каждую роль, потому что мне нужно меньше кода.
Что такое
testвнутриtestIt?