jest.mock () - не издевательский модуль в Babel 7 и React-Native 0.56 - PullRequest
0 голосов
/ 30 августа 2018

Как и многие другие, я пытаюсь обновить свое RN-приложение до React-Native 0.56, и Babel делает все так просто! (Не сарказм здесь) Я мог бы обновить RN, Реагировать на последнюю версию и заставить мое приложение компилироваться и работать, но тесты (шутка) больше не работают.

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

meeting actions › creates CLEAR_CURRENT_ATTACHMENTS when clearning current attachments

TypeError: eventActions.refreshEvents.mockImplementation is not a function

  90 |
  91 |   beforeEach(() => {
> 92 |     eventActions.refreshEvents.mockImplementation(() => ({ type: DUMMY_TYPE }));
     |                                ^
  93 |     MockDate.set(A_DATE);
  94 |     store = mockStore({
  95 |       authentication: {

  at Object.<anonymous> (src/calendar/actions/__tests__/meetingActions-test.js:92:32)

Тестовый файл с ошибкой теста (удалите все остальные тесты, чтобы упростить пример)

import moment from 'moment';
import MockDate from 'mockdate';
import configureMockStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import getToken from 'authentication/selectors/tokenSelector';
import * as actions from '../meetingActions';
import * as eventActions from '../eventActions';
import { getPlannerComments } from '../../selectors/scheduleModificationSelectors';

const {
  CLEAR_CURRENT_ATTACHMENTS,
} = actions;

jest.mock('../eventActions.js');
jest.mock('../../../authentication/selectors/tokenSelector');
jest.mock('../../selectors/scheduleModificationSelectors');

const middlewares = [thunk];
const mockStore = configureMockStore(middlewares);

describe('meeting actions', () => {
  const A_TOKEN = 'token12345';
  const AN_ID = 'h1234';
  const A_DATE = moment('2016-08-22T21:00:00.000Z');
  const AN_MEETING_EVENT = {
    start: A_DATE,
    end: A_DATE,
    guests: [],
    newGuests: [],
    newAttachments: [],
    contactsToAddToGuestList: [],
    groupsToAddToGuestList: [],
    listsToAddToGuestList: [],
  };
  const AN_ACCOUNT = { id: AN_ID };
  const DUMMY_TYPE = 'Dummy type';
  const PLANNER_COMMENTS = {};
  let store;

  beforeEach(() => {
    eventActions.refreshEvents.mockImplementation(() => ({ type: DUMMY_TYPE }));
    MockDate.set(A_DATE);
    store = mockStore({
      authentication: {
        token: A_TOKEN,
      },
      session: {
        account: AN_ACCOUNT,
      },
      meeting: AN_MEETING_EVENT,
      event: {
        attendees: [],
      },
    });
    getToken.mockImplementation(() => A_TOKEN);
    getPlannerComments.mockImplementation(() => PLANNER_COMMENTS);
  });

  it('creates CLEAR_CURRENT_ATTACHMENTS when clearing current info', () =>
    store.dispatch(actions.clearCurrentInfo())
      .then(() => {
        expect(store.getActions()).toContainEqual({ type: CLEAR_CURRENT_ATTACHMENTS });
      }));

  afterEach(() => {
    MockDate.reset();
  });
});

У меня более 800 тестов, которые не прошли из-за этой ошибки. Из того, что я понял о проблеме, это вытекает из того факта, что jest.mock

jest.mock('../domain/Attachment') // For example

на самом деле не издевается над классом. Так что Attachment выглядит как обычный класс. И поэтому фиктивная реализация функции вызывает undefined is not a function

{ [Function: Record]
  iconOf: [Function: iconOf],
  iconColorOf: [Function: iconColorOf],
  getCleanName: [Function: getCleanName],
  open: [Function: _callee2],
  parse: [Function: parse] }

Package.json

{
  "name": "MY APP",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest",
    "ios": "react-native run-ios",
    "android": "react-native run-android",
    "test:watch": "npm run test -- --watch",
    "lint": "eslint src --max-warnings=0",
    "install-dep": "npm install && cd ios && pod install"
  },
  "rnpm": {
    "assets": [
      "./src/main/themes/fonts/assets"
    ]
  },
  "jest": {
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "transform": {
      "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
    },
    "preset": "react-native",
    "collectCoverage": true,
    "setupTestFrameworkScriptFile": "<rootDir>/setup-jasmine-env.js",
    "moduleFileExtensions": [
      "js",
      "json",
      "es6",
      "ios.js",
      "android.js"
    ],
    "setupFiles": [
      "./testenv.js"
    ],
    "transformIgnorePatterns": [
      "node_modules/?!(react-native)"
    ]
  },
  "dependencies": {
    "bluebird": "^3.4.6",
    "buffer": "^5.0.0",
    "color": "^2.0.0",
    "deepmerge": "^1.5.2",
    "diacritics": "^1.2.3",
    "immutable": "^3.8.2",
    "linkify-it": "^2.0.3",
    "lodash.debounce": "^4.0.8",
    "moment": "^2.17.0",
    "prop-types": "^15.6.0",
    "react": "16.4.1",
    "react-native": "0.56.0",
    [...] // Lots of dependencies not related to the problem
    "react-navigation": "1.5.11",
    "react-redux": "^5.0.7",
    "redux": "^3.7.2",
    "redux-thunk": "^2.2.0",
    "reselect": "^3.0.1",
    "socket.io-client": "2.1.0"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0",
    "babel-core": "^6.26.3",
    "babel-eslint": "7.2.3",
    "babel-jest": "^23.4.2",
    "babel-plugin-module-resolver": "^3.1.1",
    "babel-preset-react-native": "5.0.2",
    "eslint": "^3.11.1",
    "eslint-config-airbnb": "^13.0.0",
    "eslint-import-resolver-babel-module": "5.0.0-beta.0",
    "eslint-plugin-import": "^2.12.0",
    "eslint-plugin-jsx-a11y": "^2.2.3",
    "eslint-plugin-react": "^6.7.1",
    "eslint-plugin-react-native": "^2.2.0",
    "fetch-mock": "^5.1.2",
    "istanbul": "0.4.5",
    "jasmine-reporters": "^2.2.0",
    "jest": "^23.5.0",
    "jest-cli": "23.5.0",
    "mockdate": "^2.0.1",
    "moment-timezone": "^0.5.20",
    "react-dom": "16.4.2",
    "react-test-renderer": "16.4.2",
    "redux-mock-store": "1.3.0",
    "regenerator-runtime": "^0.12.1",
    "remote-redux-devtools": "^0.5.7"
  }
}

Обратите внимание, что как и в случае нескольких выпусков в Jest, Babel и React-Native GitHubs, у меня есть Transform.

"transform": {
   "^.+\\.js$": "<rootDir>/node_modules/react-native/jest/preprocessor.js"
},

.babelrc

{
  "presets": ["react-native"],
  "plugins": [
    [
      "module-resolver",
      {
        "root": ["./src"],
        "extensions": [".js", ".ios.js", ".android.js"]
      }
    ]
  ]
}

У кого-нибудь есть идеи?

1 Ответ

0 голосов
/ 31 августа 2018

Если вы посмотрите на пример здесь , вы увидите, что mockImplementation может быть вызван только для jest.fn() объекта. В вашем случае вам нужно сначала смоделировать refreshEvents, а затем вызвать mockImplementation на эту макет:

...
eventActions.refreshEvents = jest.fn();
eventActions.refreshEvents.mockImplementation(() => ({ type: DUMMY_TYPE }));
...

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

UPDATE:

jest.mock вызовы автоматически поднимаются в начало файла с помощью преобразователя babel-jest, который вам нужен. Обратите внимание, что вы уже используете шутник. Из документов :

Если вы используете преобразователь babel-jest и хотите использовать дополнительный препроцессор кода, имейте в виду, что когда "transform" перезаписывается каким-либо образом, babel-jest больше не загружается автоматически. Если вы хотите использовать его для компиляции кода JavaScript, его необходимо явно указать.

Это означает, что вы должны явно включить преобразование babel-jest в конфигурацию jest в package.json. Это должно исправить все.

...