如何使用 browserify 重新加载模块
How can I reload module using browserify
我正在使用 Facebook 的 Dispatcher and Flux Utils React 构建应用 我正在使用 karma
、mocha
、sinon
、browserify
来测试 Flux商店。这是我的测试片段:
import {expect} from 'chai';
import sinon from 'sinon';
describe('Store', function() {
let registerSpy, Store, registeredCallback, isDispatchingStub;
beforeEach(function(done) {
const Dispatcher = require('../../../dispatcher');
registerSpy = sinon.spy(Dispatcher, 'register');
Store = require('../store');
registeredCallback = registerSpy.lastCall.args[0];
isDispatchingStub
= sinon.stub(Dispatcher, "isDispatching", function() { return true; });
done();
});
afterEach(function(done) {
registerSpy.restore();
isDispatchingStub.restore();
done();
});
it('should update its state on message', function(done) {
registeredCallback({
type: 'MESSAGE',
payload: {
message: 'Our message'
}
});
let state = Store.getState();
expect(state.size).to.equal(1);
done();
});
});
如果我只执行一个测试,一切正常。如果我添加另一个测试,我会得到一个错误,因为商店在需要时不会重新加载(我没有得到商店的新副本,它在之前的测试后已经有一些状态)。因此,registerSpy
没有 lastCall 属性 因为调度员已经注册了商店。
Dispatcher也是一样,其他store可以看到dispatched actions,所以不好测试stores。
我试过使用 rewire
但它不支持 browserify。我也试过取消 require.cache
但 Browserify 的 require 没有缓存 属性 像 node 的那样。
如何使用 browserify 获取模块的全新副本?
所以,我尝试了很多东西。
首先,我意识到我不需要浏览器来测试商店,它们不运行 DOM。所以,我使用了删除 require.cache 的解决方案。但是,就像提到的 here 它可能会导致依赖项之间的无限循环等问题。我的测试发生的第一件事是无限循环:)。
This answer 还说您可以将功能包装在一个函数中。
我一直在从像 here 这样的存储文件中导出一个实例。我从商店导出 class 并在测试文件中创建了一个实例。调度员也是一样。所以现在,我在每次测试中都有新的干净存储和调度程序。
商店示例(现在我导出商店 class 和实例):
import {ReduceStore} from 'flux/utils';
import Immutable from 'immutable';
import Dispatcher from '../../dispatcher';
export class AppMessageStore extends ReduceStore {
getInitialState() {
return Immutable.List();
}
reduce(state, action) {
switch (action.type) {
case 'APP_MESSAGE':
return Immutable.List([action.payload.message]);
default:
return state;
}
}
}
const instance = new AppMessageStore(Dispatcher);
export default instance;
测试文件(现在我从 flux utils 获得了干净的调度程序。每次测试都会创建一个新的存储,所以每个测试都有自己的存储)。
import {expect} from 'chai';
import sinon from 'sinon';
import {AppMessageStore} from '../index';
import {Dispatcher} from 'flux';
describe.only('AppMessageStore', function() {
let registerSpy, appMessageStore, registeredCallback, isDispatchingStub;
beforeEach(function(done) {
const MyDispatcher = new Dispatcher();
registerSpy = sinon.spy(MyDispatcher, 'register');
appMessageStore = new AppMessageStore(MyDispatcher);
registeredCallback = registerSpy.lastCall.args[0];
isDispatchingStub
= sinon.stub(MyDispatcher, "isDispatching", function() { return true; });
done();
});
afterEach(function(done) {
registerSpy.restore();
isDispatchingStub.restore();
done();
});
it('should update its state on message', function(done) {
registeredCallback({
type: 'APP_MESSAGE',
payload: {
message: 'Our message'
}
});
let state = appMessageStore.getState();
console.log('state.toObject()', state.toObject());
expect(state.size).to.equal(1);
done();
});
it('should blabla', function(done) {
registeredCallback({
type: 'APP_MESSAGE',
payload: {
message: 'New message'
}
});
let state = appMessageStore.getState();
console.log('state.toObject()', state.toObject());
done();
});
});
我正在使用 Facebook 的 Dispatcher and Flux Utils React 构建应用 我正在使用 karma
、mocha
、sinon
、browserify
来测试 Flux商店。这是我的测试片段:
import {expect} from 'chai';
import sinon from 'sinon';
describe('Store', function() {
let registerSpy, Store, registeredCallback, isDispatchingStub;
beforeEach(function(done) {
const Dispatcher = require('../../../dispatcher');
registerSpy = sinon.spy(Dispatcher, 'register');
Store = require('../store');
registeredCallback = registerSpy.lastCall.args[0];
isDispatchingStub
= sinon.stub(Dispatcher, "isDispatching", function() { return true; });
done();
});
afterEach(function(done) {
registerSpy.restore();
isDispatchingStub.restore();
done();
});
it('should update its state on message', function(done) {
registeredCallback({
type: 'MESSAGE',
payload: {
message: 'Our message'
}
});
let state = Store.getState();
expect(state.size).to.equal(1);
done();
});
});
如果我只执行一个测试,一切正常。如果我添加另一个测试,我会得到一个错误,因为商店在需要时不会重新加载(我没有得到商店的新副本,它在之前的测试后已经有一些状态)。因此,registerSpy
没有 lastCall 属性 因为调度员已经注册了商店。
Dispatcher也是一样,其他store可以看到dispatched actions,所以不好测试stores。
我试过使用 rewire
但它不支持 browserify。我也试过取消 require.cache
但 Browserify 的 require 没有缓存 属性 像 node 的那样。
如何使用 browserify 获取模块的全新副本?
所以,我尝试了很多东西。 首先,我意识到我不需要浏览器来测试商店,它们不运行 DOM。所以,我使用了删除 require.cache 的解决方案。但是,就像提到的 here 它可能会导致依赖项之间的无限循环等问题。我的测试发生的第一件事是无限循环:)。
This answer 还说您可以将功能包装在一个函数中。
我一直在从像 here 这样的存储文件中导出一个实例。我从商店导出 class 并在测试文件中创建了一个实例。调度员也是一样。所以现在,我在每次测试中都有新的干净存储和调度程序。
商店示例(现在我导出商店 class 和实例):
import {ReduceStore} from 'flux/utils';
import Immutable from 'immutable';
import Dispatcher from '../../dispatcher';
export class AppMessageStore extends ReduceStore {
getInitialState() {
return Immutable.List();
}
reduce(state, action) {
switch (action.type) {
case 'APP_MESSAGE':
return Immutable.List([action.payload.message]);
default:
return state;
}
}
}
const instance = new AppMessageStore(Dispatcher);
export default instance;
测试文件(现在我从 flux utils 获得了干净的调度程序。每次测试都会创建一个新的存储,所以每个测试都有自己的存储)。
import {expect} from 'chai';
import sinon from 'sinon';
import {AppMessageStore} from '../index';
import {Dispatcher} from 'flux';
describe.only('AppMessageStore', function() {
let registerSpy, appMessageStore, registeredCallback, isDispatchingStub;
beforeEach(function(done) {
const MyDispatcher = new Dispatcher();
registerSpy = sinon.spy(MyDispatcher, 'register');
appMessageStore = new AppMessageStore(MyDispatcher);
registeredCallback = registerSpy.lastCall.args[0];
isDispatchingStub
= sinon.stub(MyDispatcher, "isDispatching", function() { return true; });
done();
});
afterEach(function(done) {
registerSpy.restore();
isDispatchingStub.restore();
done();
});
it('should update its state on message', function(done) {
registeredCallback({
type: 'APP_MESSAGE',
payload: {
message: 'Our message'
}
});
let state = appMessageStore.getState();
console.log('state.toObject()', state.toObject());
expect(state.size).to.equal(1);
done();
});
it('should blabla', function(done) {
registeredCallback({
type: 'APP_MESSAGE',
payload: {
message: 'New message'
}
});
let state = appMessageStore.getState();
console.log('state.toObject()', state.toObject());
done();
});
});