Как мне издеваться над (запрос-обещание).defaults({ jar: true }) с помощью Jest?

Я пытаюсь написать тест, который использует фиктивную реализацию запроса-обещания с установленными значениями по умолчанию.

В моем коде мне требуется запрос с использованием const request = require('request-promise').defaults({ jar: true });

В моем тестовом файле я попытался

const request = require('request-promise');

jest.mock('request-promise');
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

// This returns the error 'TypeError: request is not a function'
const request = require('request-promise').defaults({ jar: true });

jest.mock('request-promise');
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

// This returns the error 'TypeError: Cannot read property 'mockImplementation' of undefined'
const request = require('request-promise').defaults({ jar: true });

jest.mock('request-promise').defaults({ jar: true });
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

// This returns the error 'TypeError: jest.mock(...).defaults is not a function'
const request = require('request-promise').defaults({ jar: true });

jest.mock(('request-promise').defaults({ jar: true }));
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

// This returns the error 'TypeError: "request-promise".defaults is not a function'

Моя функция выглядит так

const request = require('request-promise').defaults({ jar: true });

const getData = async function getData(
  previousRequestResponse,
  uniqueId,
) {

  // Below function carries out some manipulation of previous response
  const body = await getRequestBody(previousRequestResponse);

  const response = await request(method, url, body, headers)
    .then(response => JSON.parse(response.body))
    .catch((err) => {
      Logger.error('Failed');
      Logger.error(`ERROR - ${err.message}`);
      throw err;
    });

  const newResponse = manipulate(response);

  return newResponse;
};

Я хочу имитировать запрос, чтобы ответ был заглушенным значением, и я могу утверждать, что правильное значение возвращается в конце функции.


person Heather    schedule 17.04.2020    source источник
comment
Привет @Heather, не могли бы вы подробнее рассказать о том, чего вы пытаетесь достичь? Я понимаю, что у вас в коде есть что-то вроде request.defaults({ jar: true }). Что вы пытаетесь протестировать?   -  person mgarcia    schedule 18.04.2020
comment
@mgarcia Спасибо за ответ! Итак, в моем коде есть функция, которая использует запрос для выполнения нескольких вызовов стороннего API. Каждый вызов использует файлы cookie из последнего, поэтому необходимо добавить банку. Спасибо, что посмотрели @mg. При тестировании этой функции я хочу имитировать эти вызовы, используя jest.mock, чтобы вместо фактического вызова стороннего API они просто возвращали заглушку, в этом примере someVar. Затем я утверждаю, что при вызове моей функции я получаю ожидаемый результат на основе моих заглушенных данных. Надеюсь, это имеет больше смысла.   -  person Heather    schedule 18.04.2020
comment
Ммм, может быть, вы можете выполнять вызовы с помощью request-promise без необходимости имитировать вызов defaults. Если бы вы могли показать минимальную релевантную версию кода, который вы пытаетесь протестировать, я мог бы привести тестовый пример.   -  person mgarcia    schedule 18.04.2020
comment
Я попытался добавить дополнительную информацию выше и пример моего кода. Надеюсь это поможет!   -  person Heather    schedule 19.04.2020


Ответы (1)


Если вы хотите имитировать модуль request-promise, вы можете сделать это с помощью jest.mock< /a> и указав параметр factory.

Если вы должны были протестировать свой метод getData, вы можете создать фабрику, которая выглядит так:

jest.mock('request-promise', () => {
    const mock = {
        __esModule: true,
        default: (method, url, body, headers) => Promise.resolve({
            body: JSON.stringify([])
        }),
        defaults: () => mock.default
    };

    return mock;
});

С помощью этого кода ваши вызовы request всегда будут возвращать объект со свойством body, который содержит пустой массив (в виде строки, чтобы вызов JSON.parse в методе getData мог его проанализировать).

Приложение. Почему предпринятые вами попытки не увенчались успехом

Попытка 1

const request = require('request-promise');

jest.mock('request-promise');
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

Здесь вы вызываете jest.mock для модуля без заводского параметра . Таким образом, jest будет автоматически имитировать все методы модуля, и все они будут возвращать undefined при вызове. Следовательно, когда в вашем коде вы импортируете модуль и вызываете метод defaults:

const request = require('request-promise').defaults({ jar: true });

переменная request приводит к undefined. Позже, когда вы вызываете метод request, он выдает:

«TypeError: запрос не является функцией»

Попытка 2

const request = require('request-promise').defaults({ jar: true });

jest.mock('request-promise');
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

Здесь применяется та же логика, что и в предыдущей попытке. Переменная request будет undefined, и когда вы попытаетесь вызвать метод mockImplementation, она выдает:

«Ошибка типа: невозможно прочитать свойство mockImplementation неопределенного»

Попытка 3

const request = require('request-promise').defaults({ jar: true });

jest.mock('request-promise').defaults({ jar: true });
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

Здесь вы вызываете метод defaults для возвращаемого значения вызова jest.mock. Поскольку вызов jest.mock не возвращает вашу фиктивную версию модуля request-promise, он не содержит метода defaults. Итак, когда вы вызываете этот метод, он выдает:

'TypeError: jest.mock(...).defaults не является функцией'

Попытка 4

const request = require('request-promise').defaults({ jar: true });

jest.mock(('request-promise').defaults({ jar: true }));
request.mockImplementation(() => Promise.resolve(JSON.stringify(someVar)));

В этой попытке вы пытаетесь вызвать метод defaults из строки request-promise. Строки не имеют такого метода, поэтому при его вызове выдается:

'TypeError: "запрос-обещание". defaults не является функцией'

person mgarcia    schedule 19.04.2020
comment
Спасибо за объяснение - это очень полезно! - person Heather; 22.04.2020