0

我正在尝试测试依赖于 jquery-placeholder 的 REACT 组件,我已将 jsdom-setup 设置为 mocha 要求,我确实有其他使用 mocha + chai + react + 酶运行的测试,但是当我尝试安装时该组件没有使用酶的浅层,而是由于 jquery 占位符插件而失败。

现在,每当我尝试直接在组件上要求 jquery-placeholder 时,它无法加载组件并出现窗口未定义的错误,或者在访问 $.fn.placeholder 时无法访问未定义的属性,所以它可能是我的 jsdom-setup 上的东西,但我不确定它是什么,你能帮我弄清楚如何将占位符 jquery 插件添加到 mocha 所需的 jsdom-setup 或组件本身,以便我可以正确测试。

我正在从 npm 加载 jquery-placeholder 包,并使用 REACT 0.14.8

这是我的 jsdom-setup.js 文件:

var jQuery = require('jquery');
var jsdom = require('jsdom').jsdom;
var _ = require('lodash');
var mockSettings = require('./mocks/api/clinical.json');
var appStarter = require('../app/public/resources/react/app');
var exposedProperties = ['window', 'navigator', 'document', 'App'];

global.document = jsdom('');
global.window = global.document.defaultView;
global.window.locale = locale;
global.navigator = {
    userAgent: 'node.js'
};

var $ = global.jQuery = require('jquery')(global.window);
global.$ = global.jQuery;
global.window.jQuery = global.jQuery;
global.window.$ = global.jQuery;


var App = _.assign({ settings: mockSettings.settings.interactive }, mockApp);
appStarter(App);
global.window['App'] = App;

Object.keys(document.defaultView).forEach(function(property) {
    if (typeof global[property] === 'undefined') {
        exposedProperties.push(property);
        global[property] = document.defaultView[property];
    }
});

组件的这个要点(为简洁起见,省略了一些):

var React = require('react');
var ConnectApi = require('../../connect-api');
var SuggestionList = require('../layout/suggestion-list');
var i18nTools = require('../../utils/i18n');

var SearchForm = React.createClass({
    propTypes: {
        onClear: React.PropTypes.func,
        onSubmit: React.PropTypes.func,
        onSelection: React.PropTypes.func,
        currentSearch: React.PropTypes.string,
        selectBy: React.PropTypes.string,
        onPinpoint: React.PropTypes.func,
        filters: React.PropTypes.object
    },

    getInitialState: function () {
        return {
            currentSearch: this.props.currentSearch || '',
            selectBy: this.props.selectBy || '',
            currentSuggestions: [],
            submitted: false,
            locationSupported: (App.settings.geoLocation === true)
        };
    },

    componentDidMount: function () {
        var query = {};
        $('input, textarea').placeholder();

        if (this.state.currentSearch === '' ||
            App.settings.useSearchSuggestions === false) {
            return;
        }

        this.getSuggestions(this.state.currentSearch);
    },



    clearInput: function () {
        this.setState({
            submitted: false,
            currentSearch: ''
        });

        this.props.onClear();
    },


    onSubmit: function (e) {
        var query = {};
        if (e) {
            e.preventDefault();
            e.stopPropagation();
        }
        if (this.refs.search.value === '') {
            this.setState({ inputError: true });
            return;
        }

        this.setState({
            inputError: false,
            submitted: true
        });
    },


    renderSearchActions: function () {
        if (this.state.submitted) {
            return (
                <a className='searchCTA' onClick={this.clearInput} style={ { display: 'block'} }>
                    <span className='icon ion-hapi-close'></span>
                </a>
            );
        } else {
            return (
                <a className='searchCTA' onClick={this.onSubmit}>
                    <span className='icon hapi-search'></span>
                </a>
            );
        }
    },

    renderLocationActions: function() {
        if (this.state.locationSupported) {
            return (
                <a className='pinpointCTA' onClick={this.props.onPinpoint}>
                    <span className='icon hapi-geo'></span>
                </a>
            );
        } else {
            return;
        }
    },

    render: function () {
        var sPlaceholder = App.settings.strings.searchBarPlaceholder || i18nTools.translate('searchBarPlaceholder');

        return (
            <div id='searchform-wrap'>
                <form onSubmit={this.onSubmit}>
                    <div className='input-wrap search'>
                        <input type='text'
                                className={this.state.inputError ? 'error' : ''}
                                ref='search'
                                onChange={this.handleChange}
                                placeholder={sPlaceholder}
                                value={this.state.currentSearch}
                                style={ { display: 'block'} }
                                autoComplete='off' />
                        {this.renderLocationActions()}
                    </div>
                    {this.renderSearchActions()}
                </form>
                <SuggestionList onSelection={this.onSelection} sources={this.state.currentSuggestions}/>
            </div>
        );
    }
});

module.exports = SearchForm;

这是我想做的测试:

var React = require('react');
var shallow = require('enzyme').shallow;
var mount = require('enzyme').mount;
var expect = require('chai').expect;
var SearchForm = require('../components/clinical/search-form');
var sinon = require('sinon');

describe("Search Form Component", function() {
    var wrapper;
    var onSubmit;

    beforeEach(function () {
        onSubmit = sinon.spy();
    });

    afterEach(function () {
        onSubmit = null;
        wrapper = null;
    });
    describe("when submit search form", function () {
        describe("with query on search form", function  () {
            it("should call onSubmit", function () {
                wrapper = mount(<SearchForm onSubmit={onSubmit}/>);
                var search = wrapper.ref('search')
                // var input = wrapper.find('input');
                // console.log(input.ref('search'));
                // input.ref('search').node.value = "kaiser";
                // input.simulate('change', input)
                // wrapper.find('form').simulate('submit');
                // expect(onSubmit.calledOnce).to.equal(true);
            });

        });
    });
});

以防万一这是我的 gulp 测试:

gulp.task('test', ['lint'], function() {
    var mochaOpts = {
        compilers: {
            js: babel
        },
        require: ['./test/jsdom-setup.js'],
        reporter: 'spec'
    };
    if (!!opts.grep) mochaOpts.grep = opts.grep;

    return gulp.src([
        './test/components/**/*.test.js'
    ])
    .pipe(mocha(mochaOpts))
    .once('end', function () {
        process.exit();
    });
});
4

0 回答 0