简体   繁体   中英

React unit test with Jest - issue on simulating localStorage

I've an issue on unit testing a simple component (even more simplified here) :

import React, { Component } from 'react';
import Logout from '../auth/Logout';
import { logoutUser } from '../../actions/auth';

export default class Navbar extends Component {

  render() {
    const { dispatch, isAuthenticated } = this.props;

    if (isAuthenticated) {
      logStatus = <Logout onLogoutClick={() => dispatch(logoutUser())} />;
    } else {
      logStatus = (
        <Link to="/login/">
          <Button>Login</Button>
        </Link>
      );
    }

    return (
      <AppBar>        
        {logStatus}
      </AppBar>
    );
  }
}

in import { logoutUser } from '../../actions/auth';
I have a function removeItem on localStorage . I won't be using it for my test but that's where I have an error.

My test is :

test('Navbar test series', () => {
  //Enzyme testing
  it('show the login button', () => {
    const wrapper = shallow(<Navbar isAuthenticated={true} />);
    expect(wrapper.find(Login)).to.have.length(1);
  });
});

I got :

ReferenceError: localStorage is not defined      
      at Object.<anonymous> (src/axios/axios.js:8:15) [I don't know why this is here...]
      at Object.<anonymous> (src/actions/auth.js:89:38) [my logoutUser using localStorage is here ]
      at Object.<anonymous> (src/components/UI/Navbar.js:3:13)
      at Object.<anonymous> (src/components/UI/Navbar.test.js:2:15)

Doing something like suggested here How do I deal with localStorage in jest tests? :

var localStorageMock = (function () { [...]})();
Object.defineProperty(window, 'localStorage', { value: localStorageMock });

is not helping.

What I don't get is that I'm not even calling dispatch(logoutUser()) so why trying to access localStorage ?? Is the issue due to redux through dispatch ?

Thanks a lot for your help !

EDIT1 : Logout component :

import React from 'react';
import Button from '@material-ui/core/Button';

const Logout = props => (
  <Button onClick={() => props.onLogoutClick()}     color="secondary">LOGOUT</Button>
);

export default Logout;

And code from actions/auth.js and logoutUser() :

export function logoutUser() {
  return dispatch => {
    dispatch(requestLogout());
    localStorage.removeItem('token');
    dispatch(receiveLogout());
  };
}

You can add in your test files

global.localStorage = {
    getItem: () => undefined,
};

test('Navbar test series', () => {
  //Enzyme testing
  it('show the login button', () => {
    const wrapper = shallow(<Navbar isAuthenticated={true} />);
    expect(wrapper.find(Login)).to.have.length(1);
  });
});

您是否曾为该测试尝试过../../actions/auth

jest.setMock('../../actions/auth', () => ({ logoutUser: jest.fn() }))

So the solution was in :

      at Object.<anonymous> (src/axios/axios.js:8:15) [I don't know why this is here...]

Where I've found a const using localstorage on runtime. Just put it in a condition and it solved the issue.

Thanks all for the effort, it was my mistake :-(

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM