简体   繁体   English

用 Jest 运行测试,Firebase & React-Native

[英]Running Test with Jest, Firebase & React-Native

I am trying to successfully run the boiler place App-test.js test that comes with the react-native installation.我正在尝试成功运行 react-native 安装附带的 boiler place App-test.js 测试。 I have seen this test work "out of the box" with other projects, however, mine fails due to our integration with Firebase SDK. The long-term goal is to build out a test suite that mocks the calls to our firebase SDK (want to explore the following solutions: https://medium.com/stories-from-upstatement/jest-mocks-roasting-on-an-open-firestore-36fa55b76953 , How do you mock Firebase Firestore methods using Jest? ), but I am stuck at the opening gates.我已经看到这个测试在其他项目中“开箱即用”,但是,由于我们与 Firebase SDK 的集成,我的测试失败了。长期目标是构建一个测试套件来模拟对我们的调用 firebase SDK(想要探索以下解决方案: https://medium.com/stories-from-upstatement/jest-mocks-roasting-on-an-open-firestore-36fa55b76953你如何使用 Jest 模拟 Firebase Firestore 方法? ),但我我被困在开放的大门。

Here was the initial error I was receiving when trying to run the following command:这是我在尝试运行以下命令时收到的初始错误:

npm test __tests__/App-test.js

Error:错误:

import { getFirebaseRoot } from './internal/registry/namespace';
export default () => ({
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      1 | import React from 'react';
    > 2 | import firebase from '@react-native-firebase/app';
        | ^
      3 | import analytics from '@react-native-firebase/analytics';
      4 | import '@react-native-firebase/auth';
      5 | import '@react-native-firebase/database';

It appears that our App.js file is the culprit.看来我们的 App.js 文件是罪魁祸首。

import React from 'react';
import firebase from '@react-native-firebase/app';
import analytics from '@react-native-firebase/analytics';
import '@react-native-firebase/auth';
import '@react-native-firebase/database';
import '@react-native-firebase/crashlytics';
import '@react-native-firebase/functions';
import '@react-native-firebase/storage';

import { Provider } from 'react-redux';
import store from './app/store';
import Navigator from './app/routes';
import { loginUser } from './app/domain/Common/auth/actions';

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.props = props;
  }

  // gets the current screen from navigation state
  getActiveRouteName = (navigationState) => {
    let routeName = null;

    if (!navigationState) {
      return null;
    }
    const route = navigationState.routes[navigationState.index];
    // dive into nested navigators
    if (route.routes) {
      return getActiveRouteName(route);
    }

    routeName = route.routeName;

    // for venues, append specific venue name
    if (route.params && route.params.venueName) {
      routeName += ` - ${route.params.venueName}`;
    }

    return routeName;
  }

  render() {
    return (
      <Provider store={store}>
        <Navigator
          onNavigationStateChange={(prevState, currentState) => {
            // track user screen changes in  Analytics
            const currentScreen = this.getActiveRouteName(currentState);
            const prevScreen = this.getActiveRouteName(prevState);

            if (prevScreen !== currentScreen) {
              analytics().setCurrentScreen(currentScreen);
            }
          }} />
      </Provider>
    );
  }
}

After researching this issue, the most promising lead to resolve the problem appears to be the following, https://github.com/invertase/react-native-firebase/issues/3035 .在研究了这个问题之后,最有希望解决这个问题的线索如下, https://github.com/invertase/react-native-firebase/issues/3035

But I am now stuck with a new error:但我现在遇到了一个新错误:

 FAIL  __tests__/App-test.js
  ● Test suite failed to run

    /Users/kyjelly/micturnTwo/node_modules/react-native/Libraries/Utilities/warnOnce.js:15
    const warnedKeys: {[string]: boolean} = {};
          ^^^^^^^^^^

    SyntaxError: Missing initializer in const declaration

      at ScriptTransformer._transformAndBuildScript (node_modules/@jest/transform/build/ScriptTransformer.js:537:17)
      at ScriptTransformer.transform (node_modules/@jest/transform/build/ScriptTransformer.js:579:25)
      at Object.<anonymous> (node_modules/react-native/Libraries/react-native/react-native-implementation.js:14:18)

Test Suites: 1 failed, 1 total
Tests:       0 total
Snapshots:   0 total
Time:        3.101s

Here is the jest portion of my pacakge.json这是我 pacakge.json 的笑话部分

 "jest": {
    "preset": "react-native",
    "transformIgnorePatterns": [
      "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|@react-native-firebase/app)"
    ]
  }

And here is my jest.config.js这是我的 jest.config.js

module.exports = {
  verbose: true,
  moduleNameMapper: {
    '@react-native-firebase/crashlytics': '<rootDir>/__tests__/__mocks__/firebase/crashlytics.js',
  }
};

Can anyone point my in the right direction?谁能指出我正确的方向? As I understand it, Jest has issues compiling certain files that are not native Javascript. But every solution I try leads to another rabbit hole of configuration attempts.据我了解,Jest 在编译某些非本机文件 Javascript 时遇到问题。但我尝试的每个解决方案都会导致另一个配置尝试的兔子洞。

I have a fix that have worked to me and it is not related to ignoring libraries but configuring the Jest to mock the functions that I'm going to use.我有一个对我有用的修复程序,它与忽略库无关,而是将 Jest 配置为模拟我将要使用的函数。 I've followed this comment on the link you pasted.我已在您粘贴的链接上关注此评论

Finally my code looks like:最后我的代码看起来像:

export const setupModulesMock = (() => {
    jest.mock('@react-native-firebase/crashlytics', () => {
        return () => ({
            log: jest.fn(),
            recordError: jest.fn(),
            // Any function you want to use or mock
        });
    });
})();

Ideally, the package should provide the jest setup.理想情况下,package 应该提供开玩笑的设置。 However, since it's not available, you'd need to create the mock implementations for each module of the Firebase package.但是,由于它不可用,您需要为 Firebase package 的每个模块创建模拟实现。

I have placed two files - jest.config.js and jest.setup.js and the latter is referenced in the former as a value of setupFiles property of the config.我放置了两个文件 - jest.config.jsjest.setup.js ,后者在前者中被引用为配置的setupFiles属性的值。

Apart from other mock implementations, for Firebase, these are my setup.除了其他模拟实现之外,对于 Firebase,这些是我的设置。 You could modify them based on your use case.您可以根据您的用例修改它们。

const mockedFirebaseCrashlyticsLog = jest.fn()
const mockedFirebaseCrashlyticsRecordError = jest.fn()
jest.mock('@react-native-firebase/crashlytics', () => {
  return () => ({
    log: mockedFirebaseCrashlyticsLog,
    recordError: mockedFirebaseCrashlyticsRecordError
  })
})

const mockedFirebaseAuthSignInWithCustomToken = jest.fn()
jest.mock('@react-native-firebase/auth', () => () => {
  return {
    signInWithCustomToken: mockedFirebaseAuthSignInWithCustomToken
  }
})

const mockedFirestoreCollection = jest.fn()
jest.mock('@react-native-firebase/firestore', () => () => {
  return {
    collection: mockedFirestoreCollection
  }
})

const mockedFirebaseAnalyticsLogEvent = jest.fn()
const mockedFirebaseAnalyticsLogLogin = jest.fn()
const mockedFirebaseAnalyticsSetUserId = jest.fn()
jest.mock('@react-native-firebase/analytics', () => () => {
  return {
    logEvent: mockedFirebaseAnalyticsLogEvent,
    logLogin: mockedFirebaseAnalyticsLogLogin,
    setUserId: mockedFirebaseAnalyticsSetUserId
  }
})

I solved this by creating mock of @react-native-firebase/dynamic-links in this way我通过以这种方式创建@react-native-firebase/dynamic-links的模拟来解决了这个问题

jest.mock('@react-native-firebase/dynamic-links', () => {
  return () => ({
    onLink: jest.fn(),
  });
});

If you have a jest.setup.js file, or a ___mocks___ folder, you probably want to add this code to one of those:如果你有一个jest.setup.js文件,或者一个___mocks___文件夹,你可能想将这段代码添加到其中一个:

jest.mock("@react-native-firebase/analytics", () => ({
  analytics: jest.fn(() => ({
    logEvent: jest.fn(),
    setUserProperties: jest.fn(),
    setUserId: jest.fn(),
    setCurrentScreen: jest.fn(),
  })),
}));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM