测试套件无法运行 TypeError:无法读取未定义的属性“默认”

Posted

技术标签:

【中文标题】测试套件无法运行 TypeError:无法读取未定义的属性“默认”【英文标题】:Test suite failed to run TypeError: Cannot read property 'default' of undefined 【发布时间】:2018-06-14 14:26:43 【问题描述】:

我正在尝试在我的 react-native 项目中设置 Jest,但它与 bugsnag-react-native 并没有很好地配合。

使用我当前的测试配置,我看到了与 bugsnag 的 leaveBreadcrumb 函数相关的错误,如下所示:

 FAIL  app/__tests__/NetworkReducer.test.js
  ● Test suite failed to run

    TypeError: Cannot read property 'default' of undefined

      at Object.<anonymous> (app/__tests__/NetworkReducer.test.js:10:20)
          at Generator.next (<anonymous>)
          at Promise (<anonymous>)

我有一个实例化 bugsnag 的帮助文件:

helpers/bugSnag.js


//-------------------------------------------------------------------------------------------------
// Create a single instance of the bugsnag client so we don't have to duplicate our configuration
// anywhere.
//-------------------------------------------------------------------------------------------------
// https://docs.bugsnag.com/platforms/react-native/#basic-configuration

import  Client, Configuration  from 'bugsnag-react-native';
const config = new Configuration();
config.consoleBreadcrumbsEnabled = true;
config.notifyReleaseStages = ['testflight', 'production'];

const bugSnag = new Client(config);


export default bugSnag;

因此,在我的所有文件中,我从这个帮助文件中导入 bugSnag,而不是在每个文件中声明一个新客户端,尤其是在我的 NetworkReducer.js 中,bugSnag.leaveBreadcrumb('someData') 导致了我的问题。

在我的NetworkReducer.test.js 中,我正在调用模拟:

 jest.mock(bugSnag, () => 
    return 
        leaveBreadcrumb: jest.fn()
    ;
 );

我也在哪里导入bugSnag from path/to/helpers/bugSnag

如果我注释掉模拟,我会在每个具有 bugSnag.leaveBreadcrumb('someData') 的减速器类型上收到不同的错误消息,如下所示:

TypeError: _bugSnag2.default.leaveBreadcrumb is not a function

  at Object.network_prop_update (app/reducers/NetworkReducer.js:29:19)
  at app/reducers/createReducer.js:4:29
  at Object.<anonymous> (app/__tests__/NetworkReducer.test.js:80:29)
  at tryCallTwo (node_modules/promise/lib/core.js:45:5)
  at doResolve (node_modules/promise/lib/core.js:200:13)
  at new Promise (node_modules/promise/lib/core.js:66:3)

我以为我已经掌握了这个玩笑和嘲笑的方法,但我想我已经被证明是错误的。我已附上我的 Jest 的 setup.js 以供额外参考:

    jest.mock('Linking', () => 
    return 
        addEventListener: jest.fn(),
        removeEventListener: jest.fn(),
        openURL: jest.fn(),
        canOpenURL: jest.fn(),
        getInitialURL: jest.fn(),
    ;
);


jest.mock('PushNotificationios', () => 
    return 
        addEventListener: jest.fn(),
        requestPermissions: jest.fn(() => Promise.resolve()),
        getInitialNotification: jest.fn(() => Promise.resolve()),
    ;
);


jest.mock('react-native-intercom', () => 
    return 
        registerIdentifiedUser: jest.genMockFn().mockReturnValue(Promise.resolve()),
        registerUnidentifiedUser: jest.genMockFn().mockReturnValue(Promise.resolve()),
        updateUser: jest.genMockFn().mockReturnValue(Promise.resolve()),
        reset: jest.genMockFn().mockReturnValue(Promise.resolve()),
        logEvent: jest.genMockFn().mockReturnValue(Promise.resolve()),
        handlePushMessage: jest.genMockFn().mockReturnValue(Promise.resolve()),
        displayMessenger: jest.genMockFn().mockReturnValue(Promise.resolve()),
        hideMessenger: jest.genMockFn().mockReturnValue(Promise.resolve()),
        displayMessageComposer: jest.genMockFn().mockReturnValue(Promise.resolve()),
        displayMessageComposerWithInitialMessage: jest.genMockFn().mockReturnValue(Promise.resolve()),
        displayConversationsList: jest.genMockFn().mockReturnValue(Promise.resolve()),
        getUnreadConversationCount: jest.genMockFn().mockReturnValue(Promise.resolve()),
        setLauncherVisibility: jest.genMockFn().mockReturnValue(Promise.resolve()),
        setInAppMessageVisibility: jest.genMockFn().mockReturnValue(Promise.resolve()),
        setupAPN: jest.genMockFn().mockReturnValue(Promise.resolve()),
        registerForPush: jest.genMockFn().mockReturnValue(Promise.resolve()),
        setUserHash: jest.genMockFn().mockReturnValue(Promise.resolve()),
        setBottomPadding: jest.genMockFn().mockReturnValue(Promise.resolve()),
        addEventListener: jest.fn(),
        removeEventListener: jest.fn()
    ;
);


jest.mock('bugsnag-react-native', () => 
    return 
        leaveBreadcrumb: jest.fn(),
        Configuration: jest.fn(),
        Client: jest.fn()
    ;
);

【问题讨论】:

【参考方案1】:

我通过简单地将我的类变量移动到构造函数中解决了这个问题。即使我有构造函数,我仍然会收到此错误,因此将它们移入构造函数可以消除错误。还发现这里:https://github.com/facebook/react-native/issues/22437#issuecomment-445898652

【讨论】:

【参考方案2】:

虽然已经有一个公认的答案,但我今天以不同的方式解决了它。

在this answer on Github之后,我输入:

sed -i -- 's/inlineRequires: true,/inlineRequires: false,/' node_modules/react-native/jest/preprocessor.js

在我的postinstall 脚本中。我希望 Github 上的相关问题能够得到解决,但目前,我们的团队正在这样工作:-)

【讨论】:

这肯定是被接受的答案@MattyK14【参考方案3】:

这已经得到解答,但就我而言,我遇到了不同的问题。 显然 react-test-renderer 如果缺少构造函数,则无法实例化组件。

所以我需要将它们添加到我的PureComponent

constructor(props) 
    super(props)

【讨论】:

谢谢!!!作为记录,react-test-renderer 的版本 16.8.4 工作正常! @pietro909 你确定吗?刚刚用16.8.4 对其进行了测试...如果我删除构造函数,我仍然会得到相同的行为 @SamerMurad 我的同事在使用该版本时遇到了同样的问题......而“在我的机器上工作”:-) 我们现在正在调查它,虽然你是对的:那就是不是正确的解决方案。 我刚刚添加了一个我们测试过并且运行良好的不同解决方案。【参考方案4】:

我的解决方案是添加以下模拟:

jest.mock('../app/helpers/bugSnag', () => 
    return 
        leaveBreadcrumb: jest.fn(),
    ;
);

对这一切做出清晰的解释会很有帮助。

【讨论】:

啊,当然。我应该想到这一点。开玩笑,您想模拟您从中导入的 ES6 模块。所以,如果你从一个库中导入,你说import x from 'dep',然后用jest.mock('dep', () =&gt; )模拟,但由于bugSnag是一个本地文件,你通过它的路径导入它并模拟它。

以上是关于测试套件无法运行 TypeError:无法读取未定义的属性“默认”的主要内容,如果未能解决你的问题,请参考以下文章

JEST 测试套件无法运行:TypeError: (0 , _reactRedux.connect) 不是函数

Nodejs Promise TypeError:无法读取未定义的属性'then'

React JS,Firebase,TypeError:无法读取未定义的属性“initializeApp”

TypeError:无法读取未定义的属性“存在”

TypeError:无法读取未定义的属性“地址”

TypeError:无法读取未定义的属性“cwd”