【发布时间】:2017-02-09 14:08:09
【问题描述】:
过去几周我一直在学习 React、Babel、Semantic UI 和 Jest。我的组件没有在浏览器中呈现,我并没有真正遇到太多问题,但我在使用 Jest 编写单元测试时遇到了呈现问题。
SUT如下:
EditUser.jsx
var React = require('react');
var { browserHistory, Link } = require('react-router');
var $ = require('jquery');
import Navigation from '../Common/Navigation';
const apiUrl = process.env.API_URL;
const phoneRegex = /^[(]{0,1}[0-9]{3}[)]{0,1}[-\s\.]{0,1}[0-9]{3}[-\s\.]{0,1}[0-9]{4}$/;
var EditUser = React.createClass({
getInitialState: function() {
return {
email: '',
firstName: '',
lastName: '',
phone: '',
role: ''
};
},
handleSubmit: function(e) {
e.preventDefault();
var data = {
"email": this.state.email,
"firstName": this.state.firstName,
"lastName": this.state.lastName,
"phone": this.state.phone,
"role": this.state.role
};
if($('.ui.form').form('is valid')) {
$.ajax({
url: apiUrl + '/api/users/' + this.props.params.userId,
dataType: 'json',
contentType: 'application/json',
type: 'PUT',
data: JSON.stringify(data),
success: function(data) {
this.setState({data: data});
browserHistory.push('/Users');
$('.toast').addClass('happy');
$('.toast').html(data["firstName"] + ' ' + data["lastName"] + ' was updated successfully.');
$('.toast').transition('fade up', '500ms');
setTimeout(function(){
$('.toast').transition('fade up', '500ms').onComplete(function() {
$('.toast').removeClass('happy');
});
}, 3000);
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
$('.toast').addClass('sad');
$('.toast').html("Something bad happened: " + err.toString());
$('.toast').transition('fade up', '500ms');
setTimeout(function(){
$('.toast').transition('fade up', '500ms').onComplete(function() {
$('.toast').removeClass('sad');
});
}, 3000);
}.bind(this)
});
}
},
handleChange: function(e) {
var nextState = {};
nextState[e.target.name] = e.target.value;
this.setState(nextState);
},
componentDidMount: function() {
$('.dropdown').dropdown();
$('.ui.form').form({
fields: {
firstName: {
identifier: 'firstName',
rules: [
{
type: 'empty',
prompt: 'Please enter a first name.'
},
{
type: 'doesntContain[<script>]',
prompt: 'Please enter a valid first name.'
}
]
},
lastName: {
identifier: 'lastName',
rules: [
{
type: 'empty',
prompt: 'Please enter a last name.'
},
{
type: 'doesntContain[<script>]',
prompt: 'Please enter a valid last name.'
}
]
},
email: {
identifier: 'email',
rules: [
{
type: 'email',
prompt: 'Please enter a valid email address.'
},
{
type: 'empty',
prompt: 'Please enter an email address.'
},
{
type: 'doesntContain[<script>]',
prompt: 'Please enter a valid email address.'
}
]
},
role: {
identifier: 'role',
rules: [
{
type: 'empty',
prompt: 'Please select a role.'
}
]
},
phone: {
identifier: 'phone',
optional: true,
rules: [
{
type: 'minLength[10]',
prompt: 'Please enter a valid phone number of at least {ruleValue} digits.'
},
{
type: 'regExp',
value: phoneRegex,
prompt: 'Please enter a valid phone number.'
}
]
}
}
});
$.ajax({
url: apiUrl + '/api/users/' + this.props.params.userId,
dataType:'json',
cache: false,
success: function(data) {
this.setState({data: data});
this.setState({email: data.email});
this.setState({firstName: data.firstName});
this.setState({lastName: data.lastName});
this.setState({phone: data.phone});
this.setState({role: data.role});
}.bind(this),
error: function(xhr, status, err) {
console.error(this.props.url, status, err.toString());
}.bind(this)
});
},
render: function () {
return (
<div className="container">
<Navigation active="Users"/>
<div className="ui segment">
<h2>Edit User</h2>
<div className="required warning">
<span className="red text">*</span><span> Required</span>
</div>
<form className="ui form" onSubmit={this.handleSubmit} data={this.state}>
<h4 className="ui dividing header">User Information</h4>
<div className="ui three column grid field">
<div className="row fields">
<div className="column field required">
<label>First Name</label>
<input type="text" name="firstName" value={this.state.firstName}
onChange={this.handleChange}/>
</div>
<div className="column field required">
<label>Last Name</label>
<input type="text" name="lastName" value={this.state.lastName}
onChange={this.handleChange}/>
</div>
<div className="column field required">
<label>Email</label>
<input type="text" name="email" value={this.state.email}
onChange={this.handleChange}/>
</div>
</div>
</div>
<div className="ui three column grid field">
<div className="row fields">
<div className="column field required">
<label>User Role</label>
<select className="ui dropdown" name="role"
onChange={this.handleChange} value={this.state.role}>
<option value="SuperAdmin">Super Admin</option>
</select>
</div>
<div className="column field">
<label>Phone</label>
<input name="phone" value={this.state.phone}
onChange={this.handleChange}/>
</div>
</div>
</div>
<div className="ui three column grid">
<div className="row">
<div className="right floated column">
<div className="right floated large ui buttons">
<Link to="/Users" className="ui button">Cancel</Link>
<button className="ui button primary" type="submit">Save</button>
</div>
</div>
</div>
</div>
<div className="ui error message"></div>
</form>
</div>
</div>
);
}
});
module.exports = EditUser;
相关的测试文件如下:
EditUser.test.js
var React = require('react');
var Renderer = require('react-test-renderer');
var jQuery = require('jquery');
require('../../../semantic/dist/components/dropdown');
import EditUser from '../../../app/components/Users/EditUser';
it('renders correctly', () => {
const component = Renderer.create(
<EditUser />
).toJSON();
expect(component).toMatchSnapshot();
});
我在运行jest 时看到的问题:
FAIL test/components/Users/EditUser.test.js
● Test suite failed to run
ReferenceError: jQuery is not defined
at Object.<anonymous> (semantic/dist/components/dropdown.min.js:11:21523)
at Object.<anonymous> (test/components/Users/EditUser.test.js:6:370)
at process._tickCallback (node.js:369:9)
【问题讨论】:
-
我将需要知识渊博的帮助来授予此赏金,因为我对主题一无所知。有人吗?
-
这里有一个类似的问题可能会有所帮助:stackoverflow.com/questions/27189254/…
标签: jquery reactjs babeljs semantic-ui jestjs