Jest SpyOn делает функцию «неопределенной» - PullRequest
0 голосов
/ 22 октября 2018

Я создаю приложение React Native с TypeScript и пишу свои модульные тесты с использованием 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)

КСТАТИ: Проверка на getBootData также не пройдена.Я думал, что spyOn должен был оставить исходную реализацию функции без изменений?Apparently Но, видимо, он обменивается с неопределенным: (

Дополнительная информация

Вот так getToken выглядит:

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

У меня также естьпростой макет для React Native Keychain getGenericPassword в папке __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?

...