React Testing - TypeError: localStorage.getItem is not a function
React Testing - TypeError: localStorage.getItem is not a function
我在测试使用 localstorage 保存 JWT 令牌并根据身份验证为 api 调用和路由检索它的 React 组件时遇到问题。
组件本身工作正常,但是当我测试时,我在所有三个测试中都遇到了这个错误
TypeError: localStorage.getItem is not a function
这是我写的代码
home.test.js
import React from 'react';
import { shallow, mount } from 'enzyme';
import { expect } from 'chai';
import sinon from 'sinon';
import Home from '../containers/Home.jsx';
describe('<Home />', () => {
beforeAll(() => {
global.localStorage = {
i2x_token: 'someToken',
};
});
it('renders without exploding', () => {
shallow(<Home />);
});
it('renders children when passed in', () => {
const wrapper = shallow(
<Home>
<div className='unique' />
</Home>,
);
expect(wrapper.contains(<div className='unique' />)).to.equal(true);
});
it('calls componentWillMount', () => {
sinon.spy(Home.prototype, 'componentWillMount');
const wrapper = mount(<Home />);
expect(Home.prototype.componentWillMount).to.have.property('callCount', 1);
Home.prototype.componentWillMount.restore();
});
});
home.jsx
import React, { Component } from 'react';
import { browserHistory } from 'react-router';
import Header from '../components/Header.jsx';
import Content from '../components/Content.jsx';
import { API_CONTENT } from '../utils/constants';
import request from '../utils/request';
class Home extends Component {
constructor(props) {
super(props);
this.state = {
content: null,
};
this.logout = this.logout.bind(this);
}
componentWillMount() {
const token = localStorage.getItem('i2x_token');
const requestURL = API_CONTENT;
const requestObj = {
method: 'GET',
headers: new Headers({
Authorization: `JWT ${token}`,
}),
};
request(requestURL, requestObj).then((reply) => {
if (reply.results.length > 0) {
this.setState({ content: reply.results });
} else {
console.log('no reply from API');
}
});
}
logout() {
localStorage.removeItem('i2x_token');
browserHistory.push('/');
}
render() {
const data = this.state.content;
if (data !== null) {
return (
<div className='container'>
<Header logout={ this.logout } />
<Content data={ this.state.content } />
</div>
);
}
return (
<div className='container'>
<Header logout={ this.logout } />
</div>
);
}
}
export default Home;
localStorage
是您的浏览器的一部分,在单元测试中不可用,您需要模拟它。您可以在 localStorage
对象中模拟必要的方法:
home.test.js
beforeAll(() => {
global.localStorage = {
i2x_token: 'someToken',
getItem: function () {
return 'someToken'
}
};
});
....
我最近遇到了同样的问题,我使用以下方法解决了它:"mock-local-storage": "^1.0.4"
。可以找到该包 here。
此模块为您模拟了 localStorage 和 sessionStorage,这对我来说很轻松。该插件允许您向商店添加中间件,例如 redux-thunk
和 redux-sagas
.
N.B。我正在使用 Mocha 运行 我的测试。
对于其他框架你可以使用下面的配置
global.window = {}
import localStorage from 'mock-local-storage'
window.localStorage = global.localStorage
我在测试使用 localstorage 保存 JWT 令牌并根据身份验证为 api 调用和路由检索它的 React 组件时遇到问题。
组件本身工作正常,但是当我测试时,我在所有三个测试中都遇到了这个错误
TypeError: localStorage.getItem is not a function
这是我写的代码
home.test.js
import React from 'react';
import { shallow, mount } from 'enzyme';
import { expect } from 'chai';
import sinon from 'sinon';
import Home from '../containers/Home.jsx';
describe('<Home />', () => {
beforeAll(() => {
global.localStorage = {
i2x_token: 'someToken',
};
});
it('renders without exploding', () => {
shallow(<Home />);
});
it('renders children when passed in', () => {
const wrapper = shallow(
<Home>
<div className='unique' />
</Home>,
);
expect(wrapper.contains(<div className='unique' />)).to.equal(true);
});
it('calls componentWillMount', () => {
sinon.spy(Home.prototype, 'componentWillMount');
const wrapper = mount(<Home />);
expect(Home.prototype.componentWillMount).to.have.property('callCount', 1);
Home.prototype.componentWillMount.restore();
});
});
home.jsx
import React, { Component } from 'react';
import { browserHistory } from 'react-router';
import Header from '../components/Header.jsx';
import Content from '../components/Content.jsx';
import { API_CONTENT } from '../utils/constants';
import request from '../utils/request';
class Home extends Component {
constructor(props) {
super(props);
this.state = {
content: null,
};
this.logout = this.logout.bind(this);
}
componentWillMount() {
const token = localStorage.getItem('i2x_token');
const requestURL = API_CONTENT;
const requestObj = {
method: 'GET',
headers: new Headers({
Authorization: `JWT ${token}`,
}),
};
request(requestURL, requestObj).then((reply) => {
if (reply.results.length > 0) {
this.setState({ content: reply.results });
} else {
console.log('no reply from API');
}
});
}
logout() {
localStorage.removeItem('i2x_token');
browserHistory.push('/');
}
render() {
const data = this.state.content;
if (data !== null) {
return (
<div className='container'>
<Header logout={ this.logout } />
<Content data={ this.state.content } />
</div>
);
}
return (
<div className='container'>
<Header logout={ this.logout } />
</div>
);
}
}
export default Home;
localStorage
是您的浏览器的一部分,在单元测试中不可用,您需要模拟它。您可以在 localStorage
对象中模拟必要的方法:
home.test.js
beforeAll(() => {
global.localStorage = {
i2x_token: 'someToken',
getItem: function () {
return 'someToken'
}
};
});
....
我最近遇到了同样的问题,我使用以下方法解决了它:"mock-local-storage": "^1.0.4"
。可以找到该包 here。
此模块为您模拟了 localStorage 和 sessionStorage,这对我来说很轻松。该插件允许您向商店添加中间件,例如 redux-thunk
和 redux-sagas
.
N.B。我正在使用 Mocha 运行 我的测试。
对于其他框架你可以使用下面的配置
global.window = {}
import localStorage from 'mock-local-storage'
window.localStorage = global.localStorage