React TestUtils,我该如何模拟文件mouseMove?

时间:2015-06-25 16:23:28

标签: reactjs reactjs-testutils

我想在TestUtils.Simulate.mouseMove上使用document。我有一个组件Dragger,可以向mouseMove添加document事件监听器。这是一个不完整的版本:

// Dragger.js
'use strict';

var React = require('react');

export default React.createClass({
    propTypes: {
        handleDrag: React.PropTypes.func // callback set by parent
    },
    getInitialState: function() {
        return {dragging: false}
    },
    componentDidUpdate: function(props, state) {
        // 
        if (this.state.dragging && !state.dragging) {
            document.addEventListener('mousemove', this.onMouseMove)
        } else if (!this.state.dragging && state.dragging) {
            document.removeEventListener('mousemove', this.onMouseMove)
        }
    },
    onMouseDown: function(e) {
        this.setState({dragging: true})
    },
    onMouseMove: function(e) {
        // Calls back to the parent with the drag
        this.props.handleDrag(e);
    },
    render: function() {
        return <div onMouseDown={this.onMouseDown} ></div>
    }
});

我正在使用jasmine,我想确保在handleDrag后跟mouseDown之后调用mouseMove回调。

// Dragger.spec.js

var React = require('react/addons');
import Dragger from './Dragger';

var TestUtils = React.addons.TestUtils;

describe('Dragger', function() {
    it('should call the callback after drag interaction', function() {
        // make callback to spy on
        var f = {callback: function(e){return}};

        // render Dragger
        var dragger = TestUtils.renderIntoDocument(<Dragger handleDrag={f.callback} />);

        // spy on callback
        spyOn(f, 'callback');

        // simulate a mouseDown and mouseMove
        TestUtils.Simulate.mouseDown(dragger.getDOMNode(), {button: 0});
        TestUtils.Simulate.mouseMove(document);

        expect(f.callback).toHaveBeenCalled(); // FAILS!
    }
}

mouseMove事件未正确模拟。我看到2个问题

  1. 我可能需要将事件数据传递给TestUtils.Simulate.mouseMove。例如,在我将其更改为TestUtils.Simulate.mouseDown(dragger.getDOMNode())之前,调用TestUtils.Simulate.mouseDown(dragger.getDOMNode(), {button: 0})执行了而非。我应该将哪些事件数据传递给TestUtils.Simulate.mouseMove
  2. document不是测试组件呈现的detached DOM的一部分。这可能是Simulate.mouseMove无效的另一个原因。我可以在测试中使用什么而不是document
  3. 如何使用TestUtils.Simulate.mouseMove

2 个答案:

答案 0 :(得分:2)

用酶和反应的TestUtils尝试各种方法几个小时后,我终于在纯JS中创建和调度事件,这在我的开玩笑测试中起作用

it('calls handler on mouseDown on element, mouseMove on document', () => {
  const handler = jest.fn();
  const props = {
    foo: {
      uid: '1',
      resizable: true,
    },
    resizeHandler,
  };

  const instance = mount(<Header {...props} />);
  const resizer = instance.find('.resizer');
  const top = window.document.documentElement;  // target the documentElement
  resizer.simulate('mouseDown', { preventDefault: () => true });   // uses enzyme to simulate this event, adding listener to documentElement on mousemove
  const mouseMove = new Event('mousemove');  // creates a new event
  top.dispatchEvent(mouseMove);              // dispatches it
  const mouseUp = new Event('mouseup');
  top.dispatchEvent(mouseUp);
  expect(resizeHandler).toBeCalled();        // the passed in handler is called on mousemove
});

基本上,您可以使用document.documentElement找到window.document.documentElement,并像其他任何element

一样从中发送事件

答案 1 :(得分:0)

这是一篇很老的帖子,但我发现还没有发布的解决方案,我遇到了它,因为我正在写一个类似的组件。我认为问题在于你正在关注错误的事件,你应该使用onDrag进行拖动检测,这里是适合我的代码的改编版本:

// Dragger.js

import React from 'react';

export default React.createClass({
    propTypes: {
        handleDrag: React.PropTypes.func // callback set by parent
    },
    getInitialState: function() {
        return {dragging: false}
    },
    onDragStart: function(e) {
        // Calls back to the parent with the drag
        this.setState({ dragging: true });
        this.props.handleDrag(e);
    },
    onDragEnd: function() {
        this.setState({ dragging: false });
    },
    render: function() {
        return <div onDragStart={this.onDragStart} onDragEnd={this.onDragEnd}></div>;
    }
});

// Dragger.spec.js

import React from 'react';
import Dragger from '../src/Dragger';
import {
    renderIntoDocument,
    scryRenderedDOMComponentsWithTag,
    Simulate
} from 'react-addons-test-utils';

import { expect } from 'chai';

describe('Dragger', function() {
    it('should call the callback after drag interaction', function() {
        // spy on callback
        var called = false;
        // make callback to spy on
        function callback() {
            called = true;
        };

        // render Dragger
        var dragger = renderIntoDocument(<Dragger handleDrag={callback} />);

        // simulate a dragStart and dragEnd
        const element = scryRenderedDOMComponentsWithTag(dragger, 'div')[0];
        Simulate.dragStart(element);
        Simulate.dragEnd(element);
        expect(called).to.equal(true);
    });
});