реагировать нативное веб-представление на NavigationStateChange не является функцией (при запуске jest-теста) - PullRequest
0 голосов
/ 07 мая 2019

У меня есть import { WebView } from 'react-native-webview'; от реактивного сообщества. Который реализован в моем приложении-реактиве так:

<WebView
  key={ this.state.uri }
  source={{ uri: this.state.signedIn && this.state.shareUrl || this.state.uri }}
  style={{ width: '100%', height: '100%' }}
  onMessage={this.onMessage}
  onNavigationStateChange={this.setWebViewUrlChanged}
  onLoadEnd={syntheticEvent => {
    this.setState({ loading: false });
  }}
  onLoadStart={syntheticEvent => {
    this.setState({ loading: true });
  }}
/>

При запуске приложения onNavigationStateChange вызывается из запущенного приложения с вызовом webview window.location.realod(url)

Моя функция обработчика выглядит следующим образом:

setWebViewUrlChanged = webviewState => {
  if (webviewState.url !== this.state.initialUrl) {
    this.setState({ uri: webviewState.url });
  }
};

И тестируется на телефоне и эмуляторе, работает отлично. Я даже зарегистрировал состояние консоли до / после и подтвердил, что состояние обновляется и функция вызывается.

Однако я пытаюсь проверить это с помощью юнит-теста.

it('should set webview uri', () => {
  console.log(snap.children[0].children[0].children[0].children[0].props);
  snap.children[0].children[0].children[0].children[0].props.onNavigationStateChange({ url: 'some-new-url' });
  expect(snap.state().uri).toEqual('some-new-url');
});

При запуске теста выдается ошибка:

TypeError: snap.children [0] .children [0] .children [0] .children [0] .props.onNavigationStateChange не является функцией

и из строки console.log выше я получаю реквизиты webviews, где отсутствует эта функция:

  { style:
     [ { flex: 1 },
       { backgroundColor: '#ffffff' },
       { width: '100%', height: '100%' } ],
    source:
     { uri: 'https://test-domain.eu.ngrok.io/static/dashboard/index.html' },
    injectedJavaScript: undefined,
    bounces: undefined,
    scrollEnabled: undefined,
    pagingEnabled: undefined,
    cacheEnabled: true,
    decelerationRate: undefined,
    contentInset: undefined,
    automaticallyAdjustContentInsets: undefined,
    hideKeyboardAccessoryView: undefined,
    allowsBackForwardNavigationGestures: undefined,
    incognito: undefined,
    userAgent: undefined,
    onLoadingStart: [Function],
    onLoadingFinish: [Function],
    onLoadingError: [Function],
    onLoadingProgress: [Function],
    onMessage: [Function],
    messagingEnabled: true,
    onShouldStartLoadWithRequest: [Function],
    scalesPageToFit: undefined,
    allowsInlineMediaPlayback: undefined,
    mediaPlaybackRequiresUserAction: undefined,
    dataDetectorTypes: undefined,
    useSharedProcessPool: true,
    allowsLinkPreview: undefined,
    showsHorizontalScrollIndicator: undefined,
    showsVerticalScrollIndicator: undefined,
    directionalLockEnabled: undefined }

Таким образом, в тестовом визуализированном веб-просмотре только функция onMessage такая же, как в моем объекте, но все мои onLoadStart / End и onNavigationStateChange не отображаются.

Но эти функции, которые отсутствуют, прекрасно работают, когда проект компилируется и выполняется на устройстве. Как я могу это исправить, чтобы я мог включить модульные тесты для этих функций?

Снимок, используемый в тестовом примере, генерируется так:

import renderer from 'react-test-renderer';

beforeEach(async () => {
  snapshot = renderer.create(<App />);
  snap = snapshot.toJSON();
});

1 Ответ

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

Я решил это путем переключения тестового рендерера.Я установил enzyme, enzyme-to-json, enzyme-adapter-react-16

Тест изменен:

describe('with setting', () => {
  let snapshot;

  beforeEach(async () => {
    // some mocking of asyncStorage
  });

  it('should match snapshot', async () => {
    snapshot = shallow(<App />)
    await new Promise((resolve) => setTimeout(resolve, 100)); // to allow async componentDidMount to finish.
    expect(snapshot).toMatchSnapshot()
  });

  it('should set webview uri', () => {
    snapshot.find('WebView').props().onNavigationStateChange({ url: 'some-new-url' });
    expect(snapshot.state().uri).toEqual('some-new-url');
  });
});

Функция shallow происходит от настройки энзима для шутки в настройке.js

import Enzyme, { shallow, render, mount } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

// React 16 Enzyme adapter
Enzyme.configure({ adapter: new Adapter() });

// Make Enzyme functions available in all test files without importing
global.shallow = shallow;
global.render = render;
global.mount = mount;

Файл setup.js указывается в конфигурации jest (в моем случае это package.json)

"jest": {
    "preset": "react-native",
    "snapshotSerializers": [
      "enzyme-to-json/serializer"
    ],
    "setupFiles": [
      "<rootDir>/react-native/jest/setup.js"
    ]
  }

Надеюсь, что это поможет другим, у которых возникли проблемы со смещениемскомпилированных визуализированных компонентов и макетированного (тестового) визуализированного компонента.

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