Javascript 如何在具有Chai的单元测试中使用localStorage
我有一个带有react和redux的应用程序。我的测试引擎是- 在my reducer(src/my_reducer.js)中,我尝试从localStorage获取令牌,如下所示:Javascript 如何在具有Chai的单元测试中使用localStorage,javascript,unit-testing,reactjs,redux,Javascript,Unit Testing,Reactjs,Redux,我有一个带有react和redux的应用程序。我的测试引擎是- 在my reducer(src/my_reducer.js)中,我尝试从localStorage获取令牌,如下所示: const initialState = { profile: {}, token: window.localStorage.getItem('id_token') ? window.localStorage.getItem('id_token') : null, } 在我的测试文件(test/reduce
const initialState = {
profile: {},
token: window.localStorage.getItem('id_token') ? window.localStorage.getItem('id_token') : null,
}
在我的测试文件(test/reducer\u spec.js)中,我在测试用例之前导入了“my\u reducer”:
import myReducer from '../src/my_reducer'
如果我尝试运行test-localStorage(或window.localStorage)-undefined,则会出现一个错误
我需要模拟本地存储?如果需要,它在哪里?出于测试目的,我建议不要进行任何可能产生副作用的调用或在声明中调用外部模块。 因为要求/导入减速机隐式调用
window.localStorage.getItem(…)
clean测试变得很困难
我建议使用init
方法包装初始化代码,这样,如果在调用init
之前需要/导入模块,就不会发生任何事情。然后,您可以在每次之前之后
干净地设置模拟/沙箱
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()
})
})
})
第二个最佳解决方案是推迟导入,并在测试挂钩之前在中使用require
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')
})
})
})
这是因为您没有在浏览器环境中运行Chai
尝试:
我用电脑解决问题
我的运行测试命令是:
mocha -r mock-local-storage --compilers js:babel-core/register --recursive
我想你是在用摩卡做测试吧?
mocha测试在node.js中运行,node.js没有全局窗口变量。但您可以在测试中轻松创建一个:
global.window = {};
您甚至可以立即将localStorage添加到其中:
global.window = { localStorage: /* your mock localStorage */ }
模拟取决于您在本地存储中存储的内容,但对于上面的示例代码,这可能是一个合理的模拟对象:
var mockLocalStorage = {
getItem: function (key) {
if( key === 'id_token' ){ return /* a token object */; }
return null;
}
}
当然,对于不同的测试,您可以有不同的模拟,例如,另一个模拟可能总是返回null
,以测试找不到密钥的情况。无帮助:引用错误:未定义窗口您确定它来自上述代码吗?因为我们正在测试window:token:window&…是的,我敢肯定。我也很惊讶。试着实现这一点。。但是,我不使用sinonwindow.localStorage.getItem,如果找不到它,它将返回null,因此不需要检查它是否返回value@omerts,sry,我完全在编辑另一个答案。。。(我认为这比发布另一个要好?@MaxP:我可能误解了一些东西,但在我将您的模拟附加到全局上下文之前,我无法在我的ReactJS测试中访问localStorage;i、 例如:global.localStorage=window.localStorage
。请您提供一个更完整的localStorage对象测试示例好吗?@ArslArsl我已经扩展了我的答案,并在那里提供了一个示例。HTH:)获取此警告[ts]找不到名称“全局”。你能帮我一下吗?我还没有在TypeScript中尝试过,但是仅仅定义变量就足够了吗?像constglobal={}代码>还是什么?
var mockLocalStorage = {
getItem: function (key) {
if( key === 'id_token' ){ return /* a token object */; }
return null;
}
}