【问题标题】:Cannot read property 'Direction' of undefined, tests only无法读取未定义的属性“方向”,仅测试
【发布时间】:2021-05-21 16:38:46
【问题描述】:

我刚刚将TouchableOpacity 添加到一个组件中,应用程序运行良好,但我使用react-native-testing-library 的测试无法运行:

  ● Test suite failed to run

    TypeError: Cannot read property 'Direction' of undefined

      at Object.Direction (node_modules/react-native-gesture-handler/Directions.js:3:39)
      at Object.<anonymous> (node_modules/react-native-gesture-handler/GestureHandler.js:2:1)

我刚刚用纱线删除并重新添加了react-native-gesture-handler,然后运行了pod install。同样,应用程序正在运行,但测试无法运行。

我在使用&lt;Text onPress={() =&gt; onOptionPress(opt)} /&gt; 而不是TouchableOpacity 时实际上得到了同样的错误。

组件:

const SelectOptions = ({ field, dismissOverlay, onOptionPress }) => {
  return (
    <Overlay
      isVisible
      overlayStyle={styles.overlay}
      height={"auto"}
      onBackdropPress={dismissOverlay}
    >
      <View>
        {field.options.map((opt, i) => (
          <TouchableOpacity
            style={styles.option}
            key={i}
            onPress={() => onOptionPress(opt)}
          >
            <Text>{opt}</Text>
          </TouchableOpacity>
        ))}
      </View>
    </Overlay>
  );
};

测试:

describe("CardFormView", () => {
  let wrapper, birthdayField;

  beforeEach(() => {
    wrapper = render(
      <React.Fragment>
        <CardFormView form={form} />
      </React.Fragment>
    );
    birthdayField = wrapper.getByText("Add a Birthday Gift Card");
  });

  const message1 =
    "...";
  const message2 =
    "...";

  it("shows the options for a birthday card when clicked", () => {
    fireEvent.press(birthdayField);
    expect(wrapper.getByText(message1)).toBeDefined();
  });

  it("sets an option when clicked", () => {
    fireEvent.press(birthdayField);
    const firstOption = wrapper.getByText(message1);
    fireEvent.press(firstOption);
    expect(wrapper.queryByText(message2)).toBeNull();
    expect(wrapper.getByText(message1)).toBeDefined();
  });
});

【问题讨论】:

  • 你是否安装了对等依赖react-test-renderer?
  • 它在我的项目中,是的。将import "react-test-renderer"; 添加到文件中没有帮助。我需要做什么?

标签: react-native


【解决方案1】:

这是因为你没有嘲笑react-navigation-gesture-handler

要使用 react-navigation-gesture-handler 的模拟,您应该从 jest.config.json 或 jest.config.js 中的 node_modules 添加 jestSetup.js

setupFiles: [
  "./node_modules/react-native-gesture-handler/jestSetup.js"
]

我从以下链接中找到了一个参考,它对我有用。

https://github.com/software-mansion/react-native-gesture-handler/issues/344#issuecomment-489547513

【讨论】:

【解决方案2】:

对我来说,仅添加 setupFiles 不起作用。我在 package.json

"jest" 处添加了 setupFiles 和 transformIgnorePatterns

这里是使 gestureHandler 工作的代码,但我用 AsyncStorage 对其进行了测试,并且存储停止工作。如果您不使用 AsyncStorage,我想这段代码会很好用!

"setupFiles": [
     "./node_modules/react-native-gesture-handler/jestSetup.js"
],
"transformIgnorePatterns": [
     "/node_modules/(?!native-base)/"
]

我的参考: https://github.com/software-mansion/react-native-gesture-handler/issues/344

【讨论】:

  • 谢谢!我在这附近闲逛了两天!
【解决方案3】:

更新 package.json 并重新安装 npm 包对我有用。

"jest": {
    "preset": "react-native",
    "transformIgnorePatterns": ["node_modules/(?!(jest-)?react-native|@?react-navigation)"],
    "setupFiles": ["./node_modules/react-native-gesture-handler/jestSetup.js"]
}

【讨论】:

    【解决方案4】:

    发生这种情况是因为您必须从 react-native 模拟 NativeModules 模块。它可能发生在几个模块上,但它发生在我身上,特别是 ImagePickerLinking@react-navigation/native。这就是我模拟原生模块所做的。

    /src/testSetup.ts

    import {NativeModules} from 'react-native';
    
    NativeModules.RNGestureHandlerModule= {
        attachGestureHandler: jest.fn(),
        createGestureHandler: jest.fn(),
        dropGestureHandler: jest.fn(),
        updateGestureHandler: jest.fn(),
        State: {},
        Directions: {},
    },
    
    NativeModules.ImagePickerManager = {
        showImagePicker: jest.fn(),
    }
    
    NativeModules.Linking = {
        canOpenUrl: jest.fn().mockResolvedValue(true),
        openUrl: jest.fn().mockResolvedValue(true)
    }
    
    NativeModules.Platform = {
        OS: 'iOS'
    }
    
    jest.mock('react-native/Libraries/Animated/src/NativeAnimatedHelper');
    jest.mock('react-native/Libraries/Animated/src/animations/TimingAnimation');
    
    
    const mockNavigation = () => {
        const mockedNavigate = jest.fn();
        const mockedAddListener = jest.fn();
    
        jest.mock('@react-navigation/native', () => ({ // @ts-ignore
            ...(jest.requireActual('@react-navigation/native')),
            useNavigation: () => ({
              navigate: mockedNavigate,
              addListener: mockedAddListener
            })
          }));
        
        return {mockedNavigate, mockedAddListener}
    }
    
    

    在你的测试中

    import { fireEvent, act, render } = '@testing-library/react-native'
    
    const {mockedNavigate, mockedAddListener} = mockNavigation()
    
    test('Should navigate', () => {
      const { queryByText } = render(<Component />)
    
      fireEvent.press(getByText('View Page Button'))
    
      expect(mockedNavigate).toHaveBeenCalledWith('Your Page Name')
      expect(mockedAddListener).toHaveBeenCalled()
    })
    
    

    【讨论】:

      【解决方案5】:

      就我而言,遇到此问题时我使用的是react-native-cli。我删除了它并安装了@react-native-community/cli。它解决了所有问题!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-08
        • 2022-06-22
        • 2022-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-27
        相关资源
        最近更新 更多