Издевательство над собственным модулем при тестировании с помощью Jest

#testing #react-native #jestjs

#тестирование #react-native #jestjs

Вопрос:

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

 ● Test suite failed to run

TypeError: Cannot read property 'language' of undefined

  at Object.<anonymous> (node_modules/react-native-localization/LocalizedStrings.js:17:35)
  

Похоже, что ошибка вызвана этой строкой в React-Native-Localization, которая извлекает языковой стандарт устройства:

 var localization = require('react-native').NativeModules.ReactLocalization;
var interfaceLanguage = localization.language.replace(/_/g,'-');
  

Пакет используется в a wrapper , который возвращает переведенные строки компоненту, поэтому пакет не вызывается напрямую. Это выглядит примерно так:

Компонент:

 import wrapper from '../wrapper'

class component extends Component {
  render() {
    return(
      <Text>{wrapper.getString(key)}</Text>
    );
  }      

  // ...
}
  

Оболочка:

 import LocalizedStrings from 'react-native-localization'

class wrapper {

  constructor() {
    this.translations = new LocalizedStrings( ... );
  }

  getString(key) {
    return eval(`this.translations.${key}`);
  }

  // ...
}
  

Реагирование-Native-Localization:

 var localization = require('react-native').NativeModules.ReactLocalization;
var interfaceLanguage = localization.language.replace(/_/g,'-');

class LocalizedStrings {
  // ...
}
  

localization Переменная установлена вне класса, и попытка установить переменную таким образом не работает для меня и возвращает ту же ошибку:

 jest.mock('react-native-localization', () => {
  // This doesn't work
  const localization = { language: "en-US" }

  // This doesn't work either, because it hits the var initialization
  const rnl = require.requireActual('react-native-localization')
  rnl.localization = { language: "en-US" }

  // ...
})
  

Кто-нибудь знает, как издеваться над этим модулем react native?

Ответ №1:

Поскольку вы тестируете компонент, от которого зависит wrapper , вы можете mock wrapper вместо этого getString() вернуть некоторые string , которые вы можете использовать в своем тесте. Таким образом, вы не используете фактический wrapper класс, который зависит от других библиотек.

Комментарии:

1. Это то, чего я боялся. Я не хотел, чтобы mock wrapper многие вещи внутри wrapper класса действительно использовались, а это значит, что у меня тоже было бы много полезностей mock . Спасибо.

Ответ №2:

Попробуйте использовать var localization = require('react-native').NativeModules.I18nManager; вместо

Комментарии:

1. Эта строка взята из пакета npm, который я использую. Я бы предпочел избежать его разветвления. Вот строка из репозитория github с реактивной локализацией.

2. Я знаю это, но если вы измените это, я уверен, что проблема решена 😉