酶/反应单元测试

Enzyme / React Unit test

我只有这个 React 函数 UI 组件,它传入了两个 props,第二个是从其父组件传递的函数。 onClick 调用 'delegates' 到父容器组件中的一个函数,然后该父方法负责调度到 redux store。

import React, {Component} from 'react';
import PropTypes from 'prop-types';

const BotShowUI = ({ bot,  onClick  }) => {
    return(
        <div id={bot.id}  onClick={onClick}>
            {bot.id} : {bot.text}
        </div>
    )
}

BotShowUI.propTypes = {
   bot: PropTypes.object.isRequired,
   onClick: PropTypes.func.isRequired
};

export default BotShowUI;

我的测试规范是,它使用 Jasmine

import React, {Component} from 'react';
import { mount } from 'enzyme';

import BotShowUI from '../botShowUI';

function onClickFunction(){};

describe('botShowUI', () =>  {

    const bot = {id: 1, isDone: false, text: 'bot 123'};
    const expectedDivText = '1 : bot 123';

    const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />);

    it(' div has been rendered ', () => {
        expect(wrapper.find('div').first()).not.toBe(null);
    });

    it(' div displays the correct bot text ', () => {
        expect(wrapper.find('div').first().text()).toEqual(expectedDivText)
    });

    it(' div click event fired ', () => {
        wrapper.simulate('click');
        expect(wrapper.state('onClick')).toBe(true);
    });
});

最后一个断言失败

Chrome 57.0.2987 (Windows 10 0.0.0) botShowUI  div click event fired  FAILED
        TypeError: Cannot read property 'onClick' of null
            at ReactWrapper.state (webpack:///~/enzyme/build/ReactWrapper.js:825:24 <- tests.webpack.js:26303:25)
            at Object.<anonymous> (webpack:///app/react/components/bots/_tests/botShowUI.spec.js:25:23 <- tests.webpack.js:25415:25)

wrapper.simulate('click'); 有效,但下一行失败 断言点击被触发的正确方法是什么? 我是否必须放入包装器的 props/children 而不是使用状态?

我不打算以任何方式测试父容器,两者是隔离的。 此测试仅与此 UI 组件有关。

首先是 onClick 不在 state 上,而是在 props 上,所以你必须通过 wrapper.props('onClick').

来访问它

其次,检测onClick是否被处理是使用spy,而不是空函数。如果你不想使用间谍,你仍然可以这样做,但不是你做的方式。如果您有兴趣,我也可以 post 一些伪代码。但是回到使用间谍,您可以使用间谍作为 onClick 道具。下面是代码。我是手写的,所以请检查是否有任何语法错误,但你应该知道需要做什么。

it('should call the onClick handler on click', () => {
  const onClickFunction = sinon.spy()
  wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction} />)
  wrapper.simulate('click');
  expect(onClickFunction).toHaveBeenCalled();
})

根据 Abhishek 的回答,这是我对 Jasmine 的解决方案

it(' div click event fired ', () => {

    let onClickFunction_spy = jasmine.createSpy('onClickFunction');
    const wrapper = mount(<BotShowUI bot={bot} onClick={onClickFunction_spy} />); 
    wrapper.simulate('click');
    expect(onClickFunction_spy).toHaveBeenCalled();
});

希望这对任何人都有帮助。