单元测试反应组件的正确方法

时间:2017-05-28 11:54:31

标签: reactjs unit-testing jestjs

我正在使用jestenzyme来测试我的react组件,它依赖于antd - 第三个反应UI库。 为了说明的目的,我生成了足够公平的最小代码来显示我的问题。

请参阅我的test组件,如下所示:

import React from 'react';
import { Button } from 'antd';

function Test({onSubmit}) {
  return (
          <div>
           <Button htmlType="submit" type="primary" />
          </div>
         );
}

export default Test;

Q1:我将按钮模拟如下,因为单元测试要求我们隔离目标并模拟任何其他依赖项。     这是正确的吗?

__mocks__
  antd.js

antd.js

import mockComponent from '../mockComponent';

const list = [
  'Form',
  'Input',
  'Button',
  'Spin',
  'Icon'
];

const mockups = list.reduce((prev, next) => {
  prev[next] = mockComponent(next);
  return prev;
}, {});

mockups.Form.Item = mockComponent('Form.Item');

export const Form = mockups.Form;
export const Input = mockups.Input;
export const Button = mockups.Button;
export const Spin = mockups.Spin;
export const Icon = mockups.Icon;

mockComponent.js

import React from 'react';

export default function mockComponent (name) {
  return props => React.createElement(name, props, props.children);
}

Q2。即使测试通过,我也收到以下警告。我该如何解决?

test.spec.js

import React from 'react';

import { shallow, mount } from 'enzyme';
import renderer from 'react-test-renderer';

import Test from '../components/question';

describe('mount test', () => {
  let wrapper;

  let props;
  let mountedLogin;

  const test = () => {
    if (!mountedLogin) {
      mountedLogin = mount(<Test {...props} />);
    }

    return mountedLogin;
  };

  beforeEach(() => {
    mountedLogin = null;
  });

  it('always render test as the root', () => {
    const divs = test().find('div');
    expect(divs.length).toBeGreaterThan(0);
  });
});

警告

 console.error node_modules/fbjs/lib/warning.js:36
 Warning: Unknown prop `htmlType` on <Button> tag. Remove this prop from the 
 element. For details, see
    in Button (created by Unknown)
    in Unknown (created by Test)
    in div (created by Test)
    in Test (created by WrapperComponent)
    in WrapperComponent

附注,我jest中没有package.json个配置。

任何人都可以帮我解决这些问题。

非常感谢

1 个答案:

答案 0 :(得分:4)

  

Q1:我将按钮模拟如下,因为单元测试需要我们   隔离目标并模拟任何其他依赖项。就是它   正确的吗?

目前,React单元测试的推荐方法是shallow rendering。它基本上呈现给定组件一个深度。如果我们浅显示您的Test组件,则会调用render组件的Test方法,而不是render组件的Button方法。即使Button是第三方组件和依赖项,我们也不需要嘲笑它。因为我们不渲染它。但是,我们仍然可以看到它是否在组件树中并且它有正确的道具。这基本上我们将用模拟方法断言。但是,浅渲染也没有什么限制,但通常情况下,它适用于大多数场景。

但你可以显然嘲笑孩子并渲染整个组件。但这是耗时且有问题的,至少根据我的经验。

  

Q2:即使测试通过,我也会收到以下警告。怎么能   我解决了这个问题?

由于您为name传递了一个字符串React.createElement,因此React认为您要创建一个普通的HTML元素,而不是一个React组件。但由于没有HTML元素调用Button(区分大小写)并且它不知道名为htmlType的道具,因此您得到此unknown prop type warning。要阻止此警告,您可以停止将props传递给React.createElement或将模拟组件传递给React.createElement而不是name字符串。

import React from 'react';

function Mock(){
  retun (<div/>);
}

export default function mockComponent (name) {
  return props => {
    return React.createElement(Mock, {...props, name}, props.children);
  }
}

如果您需要阅读有关反应单元测试的更多信息,我建议您从反应讨论论坛中查看thread

希望这有帮助!

相关问题