我正在尝试测试依赖于jquery-placeholder的REACT组件,我将jsdom-setup设置为mocha要求,我确实有其他测试运行mocha + chai + react + enzyme,但是当我尝试安装这个组件,而不是使用酶的浅层,它因为jquery占位符插件而失败。
现在,每当我尝试直接在组件上需要jquery-placeholder时,它无法加载组件时窗口未定义错误,或者在访问$ .fn.placeholder时无法访问undefined属性,因此它可能是我的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();
});
});