开玩笑spyOn使函数“未定义”

时间:2018-10-22 12:19:19

标签: javascript reactjs typescript jestjs babel-jest

我正在使用TypeScript构建React Native应用程序,并使用Jest编写单元测试。

我目前正在为加载屏幕编写单元测试:

export class LoadingScreen extends Component<Props, object> {
  componentDidMount = () => {
    const { dispatch, navigation } = this.props;
    getToken()
      .then(key => {
        if (typeof key === "string") {
          getBootData(dispatch)
            .then(() => navigation.navigate("HomeScreen"))
            .catch(err => {
              alert(err);
              // TODO: Hide the splash screen, after componentDidMount finished.
              navigation.navigate("LoginScreen");
            });
        } else {
          // TODO: Hide the splash screen, after componentDidMount finished.
          navigation.navigate("LoginScreen");
        }
      })
      .catch(() => navigation.navigate("LoginScreen"));
  };
  // ... render() n' stuff.

如您所见,安装组件后,我检查是否有令牌。然后根据令牌的不同,我将应用程序与服务器(在getBootData中)同步加载并导航到相应的屏幕-Home或返回到Login

这是我为此生命周期方法编写的测试:

describe("life cycle methods", () => {
  describe("componentDidMount", () => {
    const props = createTestProps({});
    const wrapper = shallow<LoadingScreen>(<LoadingScreen {...props} />);
    const getTokenSpy = jest.spyOn(secureStoreFunctions, "getToken");
    const getBootDataSpy = jest.spyOn(bootDataFunctions, "getBootData");

    beforeEach(() => {
      jest.resetAllMocks();
      getBootDataSpy.mockResolvedValueOnce(true);
      wrapper.instance().componentDidMount();
    });

    it("should call getToken", () => {
      expect(getTokenSpy).toHaveBeenCalledTimes(1);
    });

    it("should call getBootData", () => {
      expect(getBootDataSpy).toBeCalledTimes(1);
    });
  });
});

我的目的是监视getToken()方法是否被调用。 但是问题在于,这会导致错误:

● LoadingScreen › life cycle methods › componentDidMount › should call getToken

    TypeError: Cannot read property 'then' of undefined

      17 |   componentDidMount = () => {
      18 |     const { dispatch, navigation } = this.props;
    > 19 |     getToken()
         |     ^
      20 |       .then(key => {
      21 |         if (typeof key === "string") {
      22 |           getBootData(dispatch)

      at LoadingScreen.componentDidMount (app/screens/Loading/LoadingScreen.tsx:19:5)
      at Object.beforeEach (app/screens/Loading/LoadingScreen.test.tsx:39:28)

BTW:getBootData的测试也失败了。 我以为spyOn应该保留功能的原始实现?但显然它与未定义的:(

其他信息

getToken的外观如下:

import { getGenericPassword } from "react-native-keychain";
export const getToken = (): Promise<boolean | string> =>
  getGenericPassword().then(
    creds => (typeof creds === "boolean" ? creds : creds.password)
  );

在与我的节点模块相邻的getGenericPassword文件夹中,我还为React Native Keychain的__mocks__/提供了一个简单的模拟,以便在需要此功能的其他测试中Jest自动模拟该功能:

const token = "abcdefghijklmnopqrstuvwxyz0123456789";
const credentials = {
  username: "session",
  password: token
};

export const setGenericPassword = jest.fn(
  (username, password) => new Promise((resolve, reject) => resolve(true)) // eslint-disable-line no-unused-vars
);

export const getGenericPassword = jest.fn(
  () => new Promise((resolve, reject) => resolve(credentials)) // eslint-disable-line no-unused-vars
);

export const resetGenericPassword = jest.fn(() => new Promise((resolve, reject) => resolve(true))); // eslint-disable-line no-unused-vars

这两个模拟可能以某种方式堆叠并导致不确定性吗?反对这一点的原因是,我没有全局getBootData模拟,如上所述,该模拟失败类似。

这是怎么回事?为什么spyOn会使函数变为undefined

0 个答案:

没有答案