笑话:如何正确测试包含promise的无效函数?

时间:2018-08-30 08:16:46

标签: unit-testing firebase react-native mocking jestjs

我正在用React Native编写一个应用程序。我使用Firebase Cloud Messaging进行实时通信。我目前正在使用Jest为FCM代码编写单元测试。问题是我在努力使其工作,因为它由包含promise的无效函数组成。让我给你代码:

fcm.js:

import { Alert } from "react-native";
import firebase from "react-native-firebase";

export const checkNotificationsPermission = () => {
  firebase
    .messaging()
    .hasPermission()
    .then(enabled => {
      if (enabled) {
        // User has permissions.
      } else {
        // User doesn't have permission.
        Alert.alert(
          alertMessages.firebasePrepareForPermissionTitle,
          alertMessages.firebasePrepareForPermissionMessage,
          [{ text: buttonTexts.ok, onPress: () => requestNotificationsPermission() }]
        );
      }
    });
};

export const requestNotificationsPermission = () => {
  firebase
    .messaging()
    .requestPermission()
    .then(() => {
      // User has authorised.
    })
    .catch(() => {
      // User has rejected permissions.
      Alert.alert(
        alertMessages.firebasePrepareForPermissionTitle,
        alertMessages.firebasePermissionDeniedMessage,
        [{ text: buttonTexts.ok, onPress: () => {} }]
      );
    });
};

fcm.test.js:

import firebase from "react-native-firebase";

describe("checkNotificationsPermission", () => {
  beforeEach(() => {
    return checkNotificationsPermission();
  });

  afterEach(() => {
    jest.clearAllMocks();
  });

  it("should call firebase's hasPermission", async () => {
    expect(firebase.messaging().requestPermission).toHaveBeenCalledTimes(1);
  });
});

这是我嘲笑Firebase(__mocks__/react-native-firebase.js)的方式:

const firebase = {
  messaging: jest.fn(() => ({
    hasPermission: jest.fn(() => new Promise(resolve => resolve(true))),
    requestPermission: jest.fn(() => new Promise(resolve => resolve(true)))
  }))
};

export default firebase;

测试失败,并显示Expected mock function to have been called one time, but it was called zero times.。由于此操作无效,并且I had a similar question涉及应答的承诺,因此我尝试将在此学到的知识应用于以下代码。

fcm.js:

import { Alert } from "react-native";
import firebase from "react-native-firebase";

export const checkNotificationsPermission = () =>
  new Promise((resolve, reject) => {
    firebase
      .messaging()
      .hasPermission()
      .then(enabled => {
        if (enabled) {
          // User has permissions.
          resolve(true);
        } else {
          // User doesn't have permission.
          Alert.alert(
            alertMessages.firebasePrepareForPermissionTitle,
            alertMessages.firebasePrepareForPermissionMessage,
            [
              {
                text: buttonTexts.ok,
                onPress: () =>
                  requestNotificationsPermission()
                    .then(() => resolve(true))
                    .catch(() => reject(false))
              }
            ]
          );
        }
      });
  });

export const requestNotificationsPermission = () =>
  new Promise((resolve, reject) => {
    firebase
      .messaging()
      .requestPermission()
      .then(() => {
        // User has authorised.
        resolve(true);
      })
      .catch(() => {
        // User has rejected permissions.
        reject(true);
        Alert.alert(
          alertMessages.firebasePrepareForPermissionTitle,
          alertMessages.firebasePermissionDeniedMessage,
          [{ text: buttonTexts.ok, onPress: () => {} }]
        );
      });
  });

fcm.test.js:

import firebase from "react-native-firebase";

import { requestNotifcationsPermission } from "./fcm";

describe("checkNotificationsPermission", () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  it("should call firebase's hasPermission", () => {
    expect.assertions(1);
    return checkNotificationsPermission().then(() => {
      expect(firebase.messaging().requestPermission).toHaveBeenCalledTimes(1);
    });
  });
});

但是由于某些原因,这些测试仍然失败。我根据经验进行了测试,并确保代码可以正常工作。只是单元测试不会通过。

编辑

我不小心遗漏了两个fcm.js也具有以下导入:

import alertMessages from "../../config/constants/alertMessages";
import buttonTexts from "../../config/constants/buttonTexts";

0 个答案:

没有答案