React (Native) setup Jest для тестирования компонента Context - PullRequest
1 голос
/ 03 мая 2019

React Context API позволяет мне размещать логику для состояния приложения в одном месте (и избегать избыточности).Прямо сейчас это выглядит так:

// Using the Context API used in react 16.3 - https://www.youtube.com/watch?v=XLJN4JfniH4
const { Provider, Consumer: ContextConsumer } = React.createContext()

class ContextProvider extends Component {

  ...// lot of functions ...

  render() {
    return (
      <Provider
        value={{
          ...this.state,
          getDose: this.getDose,
          getDoseRange: this.getDoseRange,
          setDose: this.setDose,
          checkIN: this.checkIN,
          checkOUT: this.checkOUT,
          getFalsifiedDrug: this.getDefaultproductData,
          updatePrescriptionDose: this.updatePrescriptionDose,
        }}
      >
        {this.props.children}
      </Provider>
    )
  }
}

module.exports = { ContextConsumer, ContextProvider }

Весь код можно найти здесь .

Какая лучшая практика для создания шутливых тестов, позволяющая мне тестироватьфункции и не портить состояние?

(Хотел бы избегать использования Enzyme (разработанного AirBnB) - так как AirBnB официально отказался от использования React Native)

Пример

Как мне сделать тест, который подтверждает, что когда я звоню setDose(2), productData.dose был изменен с "5 mg" и теперь равен "2 mg.Но затем установите состояние обратно на "5 mg" для другого теста.

ИНФОРМАЦИЯ О БОНУСАХ

У меня возникли проблемы с получением jest для работы со мной (поэтому я могу попробоватьпредлагаемые решения)

package.json

{
  "main": "node_modules/expo/AppEntry.js",
  "private": true,
  "scripts": {
    "test": "jest --watchAll"
  },
  "dependencies": {
    "@expo/samples": "2.1.1",
    "crypto-js": "^3.1.9-1",
    "date-fns": "^1.29.0",
    "expo": "^28.0.0",
    "invert-color": "^1.2.3",
    "lodash": "^4.17.10",
    "react": "16.3.1",
    "react-native": "https://github.com/expo/react-native/archive/sdk-28.0.0.tar.gz",
    "react-native-qrcode": "^0.2.6",
    "react-native-slider": "^0.11.0",
    "react-native-switch": "^1.5.0",
    "react-navigation": "2.3.1",
    "whatwg-fetch": "^2.0.4"
  },
  "devDependencies": {
    "babel-eslint": "^10.0.1",
    "babel-preset-expo": "^5.0.0",
    "eslint": "^5.16.0",
    "eslint-config-codingitwrong": "^0.1.4",
    "eslint-plugin-import": "^2.17.2",
    "eslint-plugin-jest": "^22.5.1",
    "eslint-plugin-jsx-a11y": "^6.2.1",
    "eslint-plugin-react": "^7.13.0",
    "jest-expo": "^32.0.0",
    "react-native-testing-library": "^1.7.0",
    "react-test-renderer": "^16.8.6"
  },
  "jest": {
    "preset": "jest-expo"
  }
}

Это просто бросает это в меня

> @ test /Users/norfeldt/Desktop/React-Native/MedBlockChain
> jest --watchAll

● Validation Error:

  Module react-native/jest/hasteImpl.js in the haste.hasteImplModulePath option was not found.
         <rootDir> is: /Users/norfeldt/Desktop/React-Native/MedBlockChain

  Configuration Documentation:
  https://jestjs.io/docs/configuration.html

npm ERR! Test failed.  See above for more details.

Я пробовал такие вещи, как

rm -rf node_modules/ yarn.lock package-lock.json && npm install

Ответы [ 3 ]

1 голос
/ 05 мая 2019

Вы можете использовать act-test-renderer , который вы уже используете в спецификациях вашего проекта.
Вам нужно позвонить testRenderer.getInstance() => проверить текущий state => вызвать некоторые методы, которые вам нужно проверить => проверить обновленный state:

import React from "react";
import { create } from "react-test-renderer";
import { ContextProvider } from "../Context";

describe("ContextProvider", () => {
  test("it updates dose correctly", () => {
    const component = create(<ContextProvider />);
    const instance = component.getInstance();

    expect(instance.getDose()).toBe(5);
    expect(instance.state.productData.dose).toBe("5 mg");

    instance.setDose(2);

    expect(instance.getDose()).toBe(2);
    expect(instance.state.productData.dose).toBe("2 mg");
  });

  test("it updates something else correctly", () => {
    // ...
  });
});

Состояние для других испытаний не будет затронуто.

Единственное, что мне нужно, чтобы эта работа работала с вашим репо, - это npm install whatwg-fetch@2.0.4 --save, как описано здесь . Надеюсь, это поможет.

enter image description here

UPDATE

Несмотря на то, что это должен быть другой вопрос, и очевидное решение состоит в том, чтобы создать новый проект rn и скопировать в него ваш код, но вот что я сделал, чтобы исправить jest ошибки в вашем коде:

1) Сделать соответствие версий (как описано в комментариях ...):

"expo": "^32.0.0",
"jest-expo": "^32.0.0",
// and maybe even
"react-native": "https://github.com/expo/react-native/archive/sdk-32.0.0.tar.gz",

2) Чтобы исправить ошибку

api.caller не является функцией

используйте babel.config.js как описано здесь :

module.exports = function(api) {
  api.cache(true);
  return {
    presets: ["babel-preset-expo"],
    env: {
      development: {
        plugins: ["transform-react-jsx-source"]
      }
    }
  };
};

3) Использование yarn в связи с этим

0 голосов
/ 06 мая 2019

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

Вы можете извлечь свои методы в "Presenter" для обработки ваших данных и только для проверки этой логики.При таком подходе легко протестировать докладчика, который имеет чистую логику ввода / вывода.

Например, докладчик может выглядеть следующим образом:

// DosePresenter.js

const processDose = (value, productData) => {
  productData.dose = value.toFixed(0) + productData.dose.replace(/[\d\.]*/g, '')
  productData.productionTime = Conventions.datetimeStr();
  productData.hashSalt = this.makeHashSalt();
  return {productData, productDataHash: getHashOfproductData(productData)};
};

module.exports = {
  processDose
};

Использование:

// Context.js

import * as DosePresenter from './DosePresenter';

const setDose = (value) => this.setState(DosePresenter.processDose(value, {...this.state}));

Теперь должно быть проще проверить логику:

// DosePresenter.test.js

describe('DosePresenter tests', () => {
  let uut;

  beforeEach(() => {
    uut = require('./DosePresenter');
  });

  it('should process a dose', () => {
    const value = 10;
    const productData = {};
    expect(uut.processDose(value, productData)).toEqual(...);
  });
};
0 голосов
/ 06 мая 2019

Если вы ищете замену для Enzyme, я думаю, вам следует поискать здесь: https://callstack.github.io/react-native-testing-library/

Эта библиотека позволит вам использовать функцию update , предоставленную для изменения значенийвы тестируете, затем меняете их обратно.

Отличная библиотека для React Native - На стартовой странице все сказано .Если вы заинтересованы в некотором коде, который поможет вам начать работу, я также могу кое-что проработать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...