Jest + супертест в NodeJS, async / await

Я пытаюсь протестировать свой 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 и создаю пользователя запроса внутри теста, он будет работать. Но я хочу больше абстракции (тестовый блок очень большой для многих тестов)

Как это исправить?

Что такое test внутри testIt?

Bergi 02.05.2018 14:18

Я не думаю, что describe поддерживает асинхронные функции.

Bergi 02.05.2018 14:18

@Bergi хороший улов, вот и все. describe описывает набор тестов с it.

Cloud_Ratha 02.05.2018 14:24

Я понимаю, что описание не поддерживает async / await. Если я перенесу тест (или его) для описания блока из функции testIt, он будет работать. Но мне нужно больше абстракции (тестовый блок очень большой для многих тестов).

Alexander Dozmorov 02.05.2018 14:32
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
5
4
11 949
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, вам нужно сообщить в шутку, что ожидание - это асинхронный метод с 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;

Но мне пришлось ограничиться одним ответом на все роли вместо индивидуального ответа на каждую роль, потому что мне нужно меньше кода.

Другие вопросы по теме