现代继电器:如何模拟继电器进行单元测试

Posted

技术标签:

【中文标题】现代继电器:如何模拟继电器进行单元测试【英文标题】:relay modern: how to mock relay for unit testing 【发布时间】:2018-02-04 10:50:39 【问题描述】:

我正在尝试测试 React Relay 现代容器,但遇到了这个问题。

TypeError: Cannot read property 'environment' of undefined

这里是测试代码:

test('render component', () => 
  const tree = renderer.create(
    <User />,
  ).toJSON();

  expect(tree).toMatchSnapshot();
);

【问题讨论】:

您需要将您的组件包装在 RelayEnvironmentProvider 中并传入 RelayMockEnvironment relay.dev/docs/guides/testing-relay-components/… 【参考方案1】:

将以下内容添加到__mocks__ 文件夹。然后在测试中将jest.mock('react-relay'); 添加到需要中继的单元测试中。这将模拟中继并只留下要测试的组件。

import React from 'react';
import PropTypes from 'prop-types';

const relayMock = jest.genMockFromModule('react-relay');

const relayChildContextTypes = 
  relay: PropTypes.object,
;

const relayEnvironment = 
  lookup: jest.fn(),
;

const relayContext = 
  relay: 
    environment: relayEnvironment,
    variables: ,
  ,
;

const relayFragmentProps = 
  relay: 
    environment: relayEnvironment,
  ,
;

const relayRefetchProps = 
  relay: 
    environment: relayEnvironment,
    refetch: jest.fn(),
  ,
;

const relayPaginationProps = 
  relay: 
    environment: relayEnvironment,
    hasMore: jest.fn(),
    loadMore: jest.fn(),
    isLoading: jest.fn(),
  ,
;

relayMock.__relayEnvironment = relayEnvironment;
relayMock.__relayFragmentProps = relayFragmentProps;
relayMock.__relayRefetchProps = relayRefetchProps;
relayMock.__relayPaginationProps = relayPaginationProps;

const makeRelayWrapper = (relayProps) => (
  (Comp) => 
    class HOC extends React.Component 
      getChildContext() 
        return relayContext;
      

      render() 
        return <Comp ...this.props ...relayProps/>;
      
    

    HOC.childContextTypes = relayChildContextTypes;
    return HOC;
  
);

relayMock.QueryRenderer = jest.fn(() => React.createElement('div', null, 'Test'));

relayMock.createFragmentContainer = makeRelayWrapper(relayFragmentProps);
relayMock.createRefetchContainer = makeRelayWrapper(relayRefetchProps);
relayMock.createPaginationContainer = makeRelayWrapper(relayPaginationProps);

module.exports = relayMock;

【讨论】:

【参考方案2】:

您实际上根本不需要模拟环境变量。我通常做的是添加:

export class User

到我要测试的类的类声明。 (确保在同一类的连接版本上保留导出默认值)。

然后我可以通过导入组件来以首选方式测试组件,而无需像我的测试中那样进行中继:

 import  User  from '../User'

这消除了对模拟中继的需要,您可以将道具干净地传递给组件。

【讨论】:

以上是关于现代继电器:如何模拟继电器进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

插座继电器测试

在 Grails 中对服务进行单元测试时如何模拟请求

如何模拟 mongodb 以进行单元测试 graphql 解析器

如何在 Angular 组件中模拟服务功能以进行单元测试

如何模拟 acegi 身份验证服务以进行单元测试?

用玩笑进行单元测试时,如何以角度模拟 ResizeObserver polyfill?