React Testing - TypeError:localStorage.getItem不是函数

时间:2017-04-25 06:21:12

标签: reactjs sinon chai jestjs enzyme

我无法测试使用localstorage来保存JWT令牌的反应组件,并根据身份验证检索api调用和路由。

组件本身工作正常,但是当我测试时,我在所有三个测试中都出现了这个错误

  

TypeError:localStorage.getItem不是函数

这是我写的代码

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;

2 个答案:

答案 0 :(得分:4)

localStorage是浏览器的一部分,在单元测试中不可用,您需要模拟它。您可以在localStorage对象中模拟必要的方法:

<强> home.test.js

beforeAll(() => {
   global.localStorage = {
      i2x_token: 'someToken',
      getItem: function () {
         return 'someToken'
      }
   };
});
....

答案 1 :(得分:1)

我最近遇到了同样的问题,我使用以下方法解决了这个问题:"mock-local-storage": "^1.0.4"。可以找到包here

这个模块为你嘲笑了 localStorage sessionStorage ,这对我来说是免费的。插件允许您向商店添加中间件,例如redux-thunkredux-sagas

N.B。我正在使用Mocha来运行我的测试。

对于其他框架,您可以使用以下配置

global.window = {}
import localStorage from 'mock-local-storage'
window.localStorage = global.localStorage