Unit testing 错误:在分派时必须调用不变冲突:Store.\u emitChange():

Unit testing 错误:在分派时必须调用不变冲突:Store.\u emitChange():,unit-testing,reactjs,reactjs-flux,jestjs,immutable.js,Unit Testing,Reactjs,Reactjs Flux,Jestjs,Immutable.js,我正在测试通量存储。我使用flux/utils中的ReduceStore,jestv0.7.0。当我使用模拟分派器分派操作时,我得到一个错误: 错误:不变冲突:存储。\uu emitChange():在分派时必须调用。 如果我在真正的浏览器中使用此应用商店,它将按预期工作 这是我的商店: import {ReduceStore} from 'flux/utils'; import Immutable from 'immutable'; import Dispatcher from '../dis

我正在测试通量存储。我使用
flux/utils
中的
ReduceStore
jest
v0.7.0。当我使用模拟分派器分派操作时,我得到一个错误:

错误:不变冲突:存储。\uu emitChange():在分派时必须调用。

如果我在真正的浏览器中使用此应用商店,它将按预期工作

这是我的商店:

import {ReduceStore} from 'flux/utils';
import Immutable from 'immutable';
import Dispatcher from '../dispatcher';
import actionConstants from '../action-constants';

class EntryStore extends ReduceStore {

  getInitialState() {
    return Immutable.List();
  }

  reduce(state, action) {
    switch (action.type) {
      case actionConstants.ENTRIES_REQUEST_SUCCESS:
        return state.merge(action.payload.entries);

      default:
        return state;
    }
  }

}

const instance = new EntryStore(Dispatcher);
export default instance;
下面是一个测试文件:

jest.autoMockOff();
jest.mock('../../dispatcher');
const actionConstants = require('../../action-constants');    

describe('EntryStore', function() {

  let Dispatcher, EntryStore, callback;

  // mock entries
  entries = [1, 2, 3];
  // mock actions
  const Immutable = require('immutable');
  const entriesRequestSuccess = {
    type: actionConstants.ENTRIES_REQUEST_SUCCESS,
    payload: {
      entries: Immutable.List(entries)
    }
  }

  beforeEach(function() {
    Dispatcher = require('../../dispatcher');
    EntryStore = require('../entry-store');
    callback = Dispatcher.register.mock.calls[0][0];
  });

  it('should update entries when entries request succeed', function(done) {
    callback(entriesRequestSuccess);
    let all = EntryStore.getState();
    expect(all.size).toBe(3);
  });

});
[编辑] 好的,我在这里提出的第一个解决方案实际上是非常错误的。它的缺点是,当真正使用
dispatch
时,它会将操作发送到所有测试的存储区。因此,你最终让所有的商店都打电话,而只测试一个商店。这可能是你不想要的副作用

所以我想出了一个更好更简单的解决方案。想法:只需模拟
调度程序的
isdispatch
方法,即可始终返回
true

这样,当调用
emitChange
方法时,您的商店就不会抱怨了。例如使用
sinon.js

sinon.stub(dispatcher, "isDispatching", function () { return true; });
看起来好多了,不是吗?:)

---------------------以前的解决方案------------------------

这不是一个可行的解决方案

看看这段代码(),因为
state.merge()
方法调用了
\uu emitChange()
方法,我想我们无法用模拟调度器测试我们的存储

因此,我没有嘲笑我的调度程序,只是在测试中调用
dispatch
方法

var dispatcher = require("path/to/appDispatcher")
     UserStore = require("path/to/userStore");

var userStore = new UserStore(dispatcher);

it("should load user datas", function () {
    var user = {
       firstname: "Felix",
       lastname: "Anon"
    };


    //actually dispatch the event
    dispatcher.dispatch(actions.RECEIVE_USER, { user: user });
    //test the state of the store
    expect(userStore.get()).to.be(user);
});

我想这是一个可以接受的解决方案,即使它不是官方文件中建议的解决方案

因此,我最终切换到堆栈
mocha
chai
sinon
,并使用找到的解决方案来测试存储,因为我使用
mocha
来测试我的其他模块。感谢@atomrc的提示,我可以使用
sinon
进行模拟,我以前不知道。