简体   繁体   中英

React Native jest test: TypeError: Cannot read property 'unsubscribeFromTopic' of undefined

I'm using react-native-fcm and jest to test my React Native app. I have a pretty basic test, it looks like this:

import 'react-native';
import React from 'react';
import PushController from '../app/PushController';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';

it('works correctly', () => {
  const tree = renderer.create(
    <PushController />
  );
});

And PushController is somewhat large, so here's the interesting parts

import React, { Component } from 'react';
import { AsyncStorage } from 'react-native';
import FCM from 'react-native-fcm';

export default class PushController extends Component {
(...)

  componentDidMount() {
    if (this.notificationListener) this.notificationListener.remove();

    this.notificationListener = FCM.on('notification', (notif) => {

        if (!notif.local_notification) {
          this.notifyUser(notif.coffee);
        }

    });
    FCM.unsubscribeFromTopic('/topics/coffee');
    FCM.subscribeToTopic('/topics/coffee');
  }
(...)

However, when running the test I get

__tests__/PushControllerTest.js
  ● works correctly

    TypeError: Cannot read property 'unsubscribeFromTopic' of undefined

      at Object.FCM.unsubscribeFromTopic (node_modules/react-native-fcm/index.js:86:15)
      at PushController.componentDidMount (app/PushController.js:44:26)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:265:25
      at measureLifeCyclePerf (node_modules/react-test-renderer/lib/ReactCompositeComponent.js:75:12)
      at node_modules/react-test-renderer/lib/ReactCompositeComponent.js:264:11
      at CallbackQueue.notifyAll (node_modules/react-test-renderer/lib/CallbackQueue.js:76:22)
      at ReactTestReconcileTransaction.ON_DOM_READY_QUEUEING.close (node_modules/react-test-renderer/lib/ReactTestReconcileTransaction.js:36:26)
      at ReactTestReconcileTransaction.TransactionImpl.closeAll (node_modules/react-test-renderer/lib/Transaction.js:206:25)
      at ReactTestReconcileTransaction.TransactionImpl.perform (node_modules/react-test-renderer/lib/Transaction.js:153:16)
      at batchedMountComponentIntoNode (node_modules/react-test-renderer/lib/ReactTestMount.js:69:27)

I've tried including lots of stuff in the test, like jest.mock('react-native-fcm') and others, but I can't get it to work at all. I get that jest automatically mocks the library, but I don't understand why FCM is undefined. Any ideas?

I managed to solve it, finally! Simply needed to change my test to

import 'react-native';
import React from 'react';
import PushController from '../app/PushController';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
import FCM from 'react-native-fcm'; // <-- This

it('works correctly', () => {
  FCM.unsubscribeFromTopic = jest.fn(); // <-- These two 
  FCM.subscribeToTopic = jest.fn();
  const tree = renderer.create(
    <PushController />
  );
});

To make sure the actual calls are mocked. I did a lot of googling before this, so I'm sure this will be useful for someone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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