Jest не обрабатывает ошибки от ожидаемого () в subscribe () RxJS наблюдаемого - PullRequest
0 голосов
/ 18 декабря 2018

Я пытался заставить Jest работать с RxJS, и у меня возникают проблемы с тем, что Jest не передает ошибки из-за обратного вызова подписки.

Вот пример теста, который я пробовал, который не работает:

import {of} from 'rxjs';

test('should fail', () => {
  of(false).subscribe(val => {
    expect(val).toBe(true);
  });
});

Приведенный выше тест не пройден, но он проходит.Я погуглил и нашел следующее решение:

Этопредлагает использовать синтаксис "done" в jest для решения проблемы.Несмотря на то, что при использовании обратного вызова «done» вышеприведенный тест завершается неудачей, при таком подходе возникает ряд проблем:

Неописуемые ошибки

Тест не пройден, поскольку вызов 'Ожидают' в подпрограмме() выдает ошибку, в результате чего 'done ()' никогда не вызывается.Время ожидания теста истекло, ожидая завершения.Таким образом, вместо того, чтобы распространять ошибку «ожидаемо», она вызывает ошибку тайм-аута, что означает, что каждый тест, который не проходит в предложении «ожидаемо», будет показывать ошибку тайм-аута вместо фактического сообщения об ошибке неудавшегося вызова «ожидание».

Тесты дольше не проходят

Поскольку все тесты не выполняются из-за ошибки тайм-аута, это означает, что для каждого теста требуется 5 секунд (тайм-аут асинхронных тестов через 5 секунд).Это может значительно увеличить время выполнения тестов

Плохое использование done

Обратный вызов done предназначен для поддержки асинхронных сценариев использования для тестирования.Но rxjs не обязательно асинхронный.Код, который я указал выше, на самом деле работает синхронно.Например, следующий тест пройдет:

import {of} from 'rxjs';

test('should pass', () => {
  let didRunSynchronously = false;
  of(true).subscribe(() => {
    didRunSynchronously = true;
  });
  expect(didRunSynchronously).toBe(true);
});

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

Интересно, если кто-то придумалхорошее решение для тестирования в rxjs, в результате которого вызовы expect будут должным образом обработаны библиотекой тестирования.

Заранее спасибо!

Соответствующие зависимости в package.json:

 "dependencies": {
    "@babel/polyfill": "^7.0.0",
    "classnames": "^2.2.6",
    "history": "^4.7.2",
    "json-stringify-pretty-compact": "^1.2.0",
    "minimist": "^1.2.0",
    "normalize.css": "^8.0.0",
    "nullthrows": "^1.1.0",
    "react": "^16.5.2",
    "react-dom": "^16.5.2",
    "react-router-dom": "^4.3.1",
    "rxjs": "^6.3.3",
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/plugin-proposal-class-properties": "^7.1.0",
    "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
    "@babel/preset-env": "^7.1.0",
    "@babel/preset-flow": "^7.0.0",
    "@babel/preset-react": "^7.0.0",
    "babel-core": "^7.0.0-bridge.0",
    "babel-env": "^2.4.1",
    "babel-eslint": "^10.0.1",
    "babel-jest": "^23.6.0",
    "babel-loader": "^8.0.4",
    "copy-webpack-plugin": "^4.5.3",
    "css-loader": "^1.0.0",
    "eslint": "^5.9.0",
    "eslint-plugin-flowtype": "^3.2.0",
    "eslint-plugin-import": "^2.14.0",
    "eslint-plugin-react": "^7.11.1",
    "eslint-watch": "^4.0.2",
    "flow-bin": "^0.83.0",
    "html-webpack-plugin": "^3.2.0",
    "jest": "^23.6.0",
    "prettier": "^1.15.3",
    "style-loader": "^0.23.1",
    "webpack": "^4.20.2",
    "webpack-cli": "^3.1.2",
    "webpack-dev-server": "^3.1.9"
  }

.babelrc file

{
  "plugins": [
    "module:@babel/plugin-proposal-class-properties",
    "module:@babel/plugin-proposal-object-rest-spread"
  ],
  "presets": [
    ["module:@babel/preset-env", { "targets": { "node": "6.10" } }],
    "module:@babel/preset-flow"
  ]
}

1 Ответ

0 голосов
/ 18 декабря 2018

Разобрался с проблемой!Оставьте это здесь для тех, кто сталкивается с подобной проблемой.RxJS и Jest работали правильно и правильно распространяли ошибки.Проблема заключалась в том, что я добавил вызов «jest.useFakeTimers» в сценарий тестирования.По какой-то причине это приводило к тому, что ошибки не распространялись должным образом в тесте.Мне нужно было добавить "jest.runAllTimers", чтобы получить ошибки.Вот полный тестовый скрипт, реализованный правильно:

import {of} from 'rxjs';

jest.useFakeTimers();

test('should fail', () => {
  of(false).subscribe(val => {
    expect(val).toBe(true);
  });
  jest.runAllTimers();
});

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

...