使用酶+ React Native + Jest测试时,常量未定义

时间:2018-08-08 17:17:01

标签: unit-testing react-native constants jestjs enzyme

我想用酶和Jest对我的React Native组件进行单元测试。

这是一个QR扫描仪,可在成功扫描后调用功能。该函数与服务器通信并返回响应。然后,它使用switch语句来确定下一步要做什么。当我仅使用该应用程序时,该组件及其功能可以正常运行。但是此功能的单元测试失败,因为所有常量都未定义。我该如何解决?

作为参考,这是我的单元测试的代码(为清晰起见,已剥离):

import React from "react";
import { shallow } from "enzyme";
import { Alert, View } from "react-native";

import * as qrCodeFunctions from "../../api/qrCodes/qrCodes";
import { ScannerScreen } from "./ScannerScreen";

Alert.alert = jest.fn();

const createTestProps = props => ({
  navigation: { navigate: jest.fn() },
  setData: jest.fn(),
  ...props
});

describe("ScannerScreen", () => {
  describe("rendering", () => {
    let wrapper;
    let props;
    beforeEach(() => {
      props = createTestProps();
      wrapper = shallow(<ScannerScreen {...props} />);
    });

    it("should render a <View />", () => {
      expect(wrapper.find(View)).toHaveLength(1);
    });

    it("should render a <QRCodeScanner />", () => {
      expect(wrapper.find("QRCodeScanner")).toHaveLength(1);
    });
  });

  describe("interaction", () => {
    let wrapper;
    let props;
    beforeEach(() => {
      props = createTestProps();
      wrapper = shallow(<ScannerScreen {...props} />);
    });

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

    describe("scanning the qr code", () => {
      describe("data received", () => {
        qrCodeFunctions.executeQRCodeFunction = jest.fn(
          () =>
            new Promise(resolve =>
              resolve({
                entities: {
                  houses: {
                    "b813d3d1-9fdb-47bf-92ee-f7cb8bd6564b": {
                      category: "villa",
                      price: 2.400.000,
                      uuid: "b813d3d1-9fdb-47bf-92ee-f7cb8bd6564b"
                    }
                  },
                  ...
                },
                result: {
                  detail: "Successfully received villas.",
                  qrCodeData: "aeb1717f-480f-415f-9d15-00906750cae2"
                }
              })
            )
        );
        it("should dispatch an event to set the data and show an alert", () => {
          wrapper.instance().onRead({ data: { v1QRCodeData: "abc" } });
          expect(qrCodeFunctions.executeQRCodeFunction).toHaveBeenCalledTimes(1);
          expect(props.setData).toHaveBeenCalledTimes(1);
          expect(Alert.alert).toHaveBeenCalledTimes(1);
        });
      });
    });
  });
});

props.setData应该根据switch语句(在未进行单元测试时调用),如下所示:

  onRead = e => {
    executeQRCodeFunction(e.data.v1QRCodeData)
      .then(data => {
        console.log(data.result);
        console.log(SERVER_VALUES_QR_CODE_DETAIL_VILLAS_RECEIVED);
        console.log(data.result.detail);
        console.log(data.result.detail == SERVER_VALUES_QR_CODE_DETAIL_VILLAS_RECEIVED);
        switch (data.result.detail) {
          case SERVER_VALUES_QR_CODE_DETAIL_VILLAS_RECEIVED:
            this.villasReceived(data);
            break;
          ...
          default:
            alert(data.result);
        }
      })
      .catch(error => {
        alert(error);
      });
  };

函数villasReceived然后调用setData。但是在单元测试中,这永远不会发生,因为切换用例始终是指默认用例。此外,控制台日志的结果是data.resultdata.result.detail是正确的,但是比较的结果是false和常数undefined

1 个答案:

答案 0 :(得分:0)

遇到类似的问题;我的Jest测试在我的其中一个模块的这一行上因TypeError: Cannot read property 'manifest' of undefined而失败:

import { Constants } from 'expo';

...

  const storeVersion = Constants.manifest.version;    // test fails here

...

解决方案

您可以在Jest文档中关注mock a node module

我创建了一个文件\__mocks__\expo.js__mocks__文件夹必须与node_modules文件夹相邻),

const Constants = {
  manifest: {
    version: '1.0.0',
  },
};

export {
  Constants
};

很显然,您将构造一个包含所需属性的虚拟Constants对象。