Тестирование трафарета e2e: макетирование функции в контексте браузера кукловода - PullRequest
0 голосов
/ 06 апреля 2020

У меня есть компонент Stencil, который использует ax ios .get для получения некоторых данных с сервера (например, localhost: 3000 во время разработки). Теперь у меня есть тест e2e.ts, который тестирует этот компонент в сочетании с несколькими другими компонентами. Я хотел бы издеваться над функцией ax ios .get, чтобы изолировать мои тесты от сервера. В тесте spe c .ts я бы издевался над топором ios, используя jest со следующим кодом:

import axios from 'axios';
import {myComponent} from './my-component';

const mock = jest.spyOn(axios, 'get');

test('get data', async () => {
  ...
  mock.mockResolvedValue('hello');
  ...
});

Но это не работает в тестах e2e. Я попытался установить jest-puppeteer, но я не могу найти примеров того, как вы могли бы смоделировать функцию с помощью jest mopping API с помощью jest-puppeteer.

Любой пример кода был бы очень признателен.

PS Примечание: если я использую Puppeteer для перехвата запроса и ответа на него, я получаю ошибку «Запрос уже обработан». Вот пример кода:

const page = await newE2EPage();
await page.setRequestInterception(true);
page.on('request', req => {
  if(req.url() === 'http://localhost:3000/') {
    request.respond({
      contentType: 'text/plain',
      headers: {'Access-Control-Allow-Origin': '*'},
      body: 'hello'
    })
  }
  else {
    request.continue({});
  }
});
await page.setContent('<my-component></my-component>');

1 Ответ

1 голос
/ 15 апреля 2020

Я не уверен на 100%, насколько хорошо этот ответ преобразуется в axios, но это возможно с fetch, который я рекомендую вам использовать, потому что он широко поддерживается браузерами, и Stencil автоматически заполняет его при необходимости.

Для тестов e2e нашего приложения я написал следующий скрипт, который можно добавить на страницу e2e после его инициализации:

await page.addScriptTag({
  content: `
    window.originalFetch = window.fetch;

    window.requestsToIntercept = [];

    window.fetch = (...args) => (async(args) => {
      const result = await this.originalFetch(...args);

      for (const request of requestsToIntercept) {
        if (args[0].includes(request.url)) {
          result.json = async () => JSON.parse(request.response);
          result.text = async () => request.response;
        }
      }

      return result;
    })(args);`,
});

Он перезаписывает реализацию fetch и использует глобальный массив requestsToIntercept для ответов на заглушки. Вы можете добавить вспомогательную функцию к своему коду, например

const interceptRequests = async (requests: { url: string; response: string }[]) =>
  page.addScriptTag({
    content: `window.requestsToIntercept.push(...${JSON.stringify(requests)});`
  });

, а затем использовать ее как

interceptRequests([{ url: '/foo', response: { foo: 'bar' } }])

. Она будет перехватывать все запросы, которые включают /foo, и вместо этого отвечать заданным ответом. .


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


Кстати, причина, по которой вы не можете включить перехват запросов в Puppeteer в том, что Stencil уже использует его внутри, и, следовательно, запрос уже будет обработан до того, как ваш слушатель «по запросу» включится (как говорится в сообщении об ошибке). На Github есть просьба изменить это: https://github.com/ionic-team/stencil/issues/2326.

...