经过3天的研究而不是在任何地方,我决定向这里询问已经有类似经历或可以指出更好的路径的人。
我发现的更好的问题是这个,但在空中留下了一些问题:React - how to test form submit?
因为我是先生,所以我相信我可能会出错,但不确定是哪一个。如果这是我构建组件的方式,甚至是测试概念本身。
我有以下情况:
我的代码到现在为止:
登录组件
class Login extends React.Component {
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleSubmit(e) {
e.preventDefault();
this.props.sendLoginRequest(this.state).then(
({data}) => {
console.log(data);
},
(data) => {
console.error(data);
}
);
}
handleChange(e) {
this.setState({ [e.target.name]: e.target.value });
}
render() {
return (
<div id='auth-container' className='login'>
<Form onSubmit={this.handleSubmit}>
<FormGroup controlId='emailaddress'>
<InputGroup bsSize='large'>
<InputGroup.Addon>
<Icon glyph='icon-fontello-mail' />
</InputGroup.Addon>
<FormControl
autoFocus
className='border-focus-blue'
type='email'
placeholder='email@fixdin.com'
name='email'
onChange={this.handleChange}
value={this.state.email} />
</InputGroup>
</FormGroup>
<FormGroup controlId='password'>
<InputGroup bsSize='large'>
<InputGroup.Addon>
<Icon glyph='icon-fontello-key' />
</InputGroup.Addon>
<FormControl
className='border-focus-blue'
type='password'
placeholder='password'
name='password'
onChange={this.handleChange}
value={this.state.password} />
</InputGroup>
</FormGroup>
</Form>
</div>
)
}
}
Login.propTypes = {
sendLoginRequest: React.PropTypes.func.isRequired
}
authAction.js
import createApi from '../services/api';
import { saveToken } from '../services/session';
export function sendLoginRequest(loginData) {
return dispatch => {
const api = createApi();
const loginPromise = api.post('auth/', loginData);
loginPromise.then(
({ data }) => {
saveToken(data.token);
}
);
return loginPromise;
}
}
API..js
import axios from 'axios';
import { isAuthenticated, getToken } from './session';
export const BASE_URL = 'http://localhost:8000/api/v1/';
export default function createAPI() {
let auth = { }
if (isAuthenticated()) {
auth = {
Token: getToken()
}
}
return axios.create({
baseURL: BASE_URL,
auth: auth
});
};
session.js
const TOKEN_KEY = 'token';
export function saveToken(value)
{
localStorage.setItem(TOKEN_KEY, value);
}
export function getToken()
{
return localStorage.getItem(TOKEN_KEY)
}
export function isAuthenticated() {
return getToken() !== null;
}
我的测试堆栈是Mocha / Chai / Enzyme / sinon,它的定义是
setup.js
var jsdom = require('jsdom');
class LocalStorageMock {
constructor() {
this.store = {};
}
clear() {
this.store = {};
}
getItem(key) {
return this.store[key];
}
setItem(key, value) {
this.store[key] = value.toString();
}
};
if(!global.document) {
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = document.defaultView;
global.navigator = {userAgent: 'node.js'};
global.localStorage = new LocalStorageMock;
}
登录-test.js
import React from 'react';
import sinon from 'sinon';
import { mount, shallow } from 'enzyme';
import { expect } from 'chai';
import { Provider } from 'react-redux';
import axios from 'axios'
import moxios from 'moxios'
import store from './../src/store';
import LoginPage from './../src/auth/components/Login';
describe('Login', () => {
beforeEach(function () {
moxios.install(axios)
})
afterEach(function () {
moxios.uninstall(axios)
})
it('should call action on form submit', () => {
const submitRequest = sinon.stub(LoginPage.prototype, 'handleSubmit').returns(true);
const wrapper = mount(<Provider store={store}><LoginPage /></Provider>);
wrapper.find('form').simulate('submit');
expect(submitRequest.called).to.be.true;
submitRequest.restore();
});
it('should save token on succesfull login', () => {
const wrapper = mount(<Provider store={store}><LoginPage /></Provider>);
const emailInput = wrapper.find('input[type="email"]');
const passInput = wrapper.find('input[type="password"]');
const form = wrapper.find('form');
emailInput.value = "valid@email.com";
passInput.value = '123456789';
form.simulate('submit'); // Should I use submit button instead???
moxios.wait(function () {
let request = moxios.requests.mostRecent()
request.respondWith({
status: 200,
response:
{ Token: 'validToken' }
}).then(function () {
expect(localStorage.getItem('Token')).to.equal('validToken');
});
});
});
});
以上测试未通过,因为它为submitRequest.called
返回false,第二次测试失败,错误为"Cannot read property 'respondWith' of undefined"
。我不确定如何修复等等,我不确定我是否理想化了它!
在对它进行大量研究时,我已经看到了具有针对组件方法调用+隔离动作测试的测试的示例。 所以......
mostRecent()
未定义。提前致谢。