te')); return $arr; } /* 遍历用户所有主题 * @param $uid 用户ID * @param int $page 页数 * @param int $pagesize 每页记录条数 * @param bool $desc 排序方式 TRUE降序 FALSE升序 * @param string $key 返回的数组用那一列的值作为 key * @param array $col 查询哪些列 */ function thread_tid_find_by_uid($uid, $page = 1, $pagesize = 1000, $desc = TRUE, $key = 'tid', $col = array()) { if (empty($uid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('uid' => $uid), array('tid' => $orderby), $page, $pagesize, $key, $col); return $arr; } // 遍历栏目下tid 支持数组 $fid = array(1,2,3) function thread_tid_find_by_fid($fid, $page = 1, $pagesize = 1000, $desc = TRUE) { if (empty($fid)) return array(); $orderby = TRUE == $desc ? -1 : 1; $arr = thread_tid__find($cond = array('fid' => $fid), array('tid' => $orderby), $page, $pagesize, 'tid', array('tid', 'verify_date')); return $arr; } function thread_tid_delete($tid) { if (empty($tid)) return FALSE; $r = thread_tid__delete(array('tid' => $tid)); return $r; } function thread_tid_count() { $n = thread_tid__count(); return $n; } // 统计用户主题数 大数量下严谨使用非主键统计 function thread_uid_count($uid) { $n = thread_tid__count(array('uid' => $uid)); return $n; } // 统计栏目主题数 大数量下严谨使用非主键统计 function thread_fid_count($fid) { $n = thread_tid__count(array('fid' => $fid)); return $n; } ?>javascript - How to use localStorage in unit tests with Chai - Stack Overflow
最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to use localStorage in unit tests with Chai - Stack Overflow

programmeradmin3浏览0评论

I have an app with react and redux. My test engine is - Chai

In my reducer (src/my_reducer.js), I try to get token from localStorage like this:

const initialState = {
  profile: {},
  token: window.localStorage.getItem('id_token') ? window.localStorage.getItem('id_token') : null,
}

In my tests file (test/reducer_spec.js) I have import 'my_reducer' before test cases:

import myReducer from '../src/my_reducer'

And I have an error, if I try to run test - localStorage (or window.localStorage) - undefined.

I need to mock localStorage? If I need, where is the place for it?

I have an app with react and redux. My test engine is - Chai

In my reducer (src/my_reducer.js), I try to get token from localStorage like this:

const initialState = {
  profile: {},
  token: window.localStorage.getItem('id_token') ? window.localStorage.getItem('id_token') : null,
}

In my tests file (test/reducer_spec.js) I have import 'my_reducer' before test cases:

import myReducer from '../src/my_reducer'

And I have an error, if I try to run test - localStorage (or window.localStorage) - undefined.

I need to mock localStorage? If I need, where is the place for it?

Share Improve this question edited Oct 13, 2021 at 15:45 AncientSwordRage 7,63521 gold badges99 silver badges191 bronze badges asked May 18, 2016 at 16:07 Max PMax P 1,4594 gold badges15 silver badges33 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 7

I presume you are running your tests with mocha? mocha tests run in node.js, and node.js does not have a global window variable. But you can easily create one in your tests:

global.window = {};

You can even add the localStorage to it immediately:

global.window = { localStorage: /* your mock localStorage */ }

The mock depends on what you store in your local storage, but for the example code above this might be a reasonable mock object:

var mockLocalStorage = {
    getItem: function (key) {
        if( key === 'id_token' ){ return /* a token object */; }
        return null;
    }
}

Of course, for different tests you can have different mocks, e.g. another mock might always return null to test the case that the key cannot be found.

I solve problem with mock-local-storage My run test mand is:

mocha -r mock-local-storage --pilers js:babel-core/register --recursive

For testing purposes I remend not to make any calls which may have side effects or call external modules in declarations. Because requiring / importing your reducer implicitly calls window.localStorage.getItem(...) clean testing gets hard.

I'd suggest to wrap your initialization code with a init method so nothing happens if you require/import your module before calling init. Then you can use beforeEach afterEach to cleanly setup mocks/sandboxes.

import myReducer from '../src/my_reducer'
describe('with faked localStorage', function() {
  var sandbox

  beforeEach(function() {
    sandbox = sinon.sandbox.create()
    // fake window.localStorage
  })

  afterEach(function() {
    sandbox.restore()
  })

  describe('the reducer', function() {
    before(function() {
      myReducer.init()
    })
  })
})

The second best solution is to postpone the import and use require within the before test hook.

describe('with fake localStorage', function() {
  var sandbox

  beforeEach(function() {
    sandbox = sinon.sandbox.create()
    // fake window.localStorage
  })

  afterEach(function() {
    sandbox.restore()
  })

  describe('the reducer', function() {
    var myReducer

    before(function() {
      myReducer = require('../src/my_reducer')
    })

  })
})

It is because you are not running Chai in a browser environment.

Try:

  // Make sure there is a window object available, and that it has localstorage (old browsers don't)
  const initialState = {
    profile: {},
    // window.localStorage.getItem('id_token') will return null if key not found
    token: window && window.localStorage ? window.localStorage.getItem('id_token') : null,
  }
发布评论

评论列表(0)

  1. 暂无评论