Testing flux stores with mocha, chai and sinon

2019-04-11 23:10发布

I'm trying to test Flux stores with Mocha, Chai and Sinon. I've been searching for examples but couldn't find enough information to make my tests work.

I've tried many things but I'm quite blocked. This is what I have now.

Source

MyStore.js

var AppDispatcher = require('../dispatcher/AppDispatcher');
var EventEmitter = require('events').EventEmitter;
var MyStoreConstants = require('../constants/MyConstants');
var assign = require('object-assign');

var CHANGE_EVENT = 'change';

var _results = [];

function setResults(values) {
    _results = values;
}

var MyStore = assign({}, EventEmitter.prototype, {
    getResults: function () {
        return _results;
    },
    emitChange: function () {
        this.emit(CHANGE_EVENT);
    },
    addChangeListener: function (callback) {
        this.on(CHANGE_EVENT, callback);
    },
    removeChangeListener: function (callback) {
        this.removeListener(CHANGE_EVENT, callback);
    }
});

AppDispatcher.register(function (action) {
    switch (action.actionType) {
        case MyConstants.SET_RESULTS:
            setResults(action.values);
            MyStore.emitChange();
            break;
        default:
            console.log('unknown action');
     }
});

module.exports = MyStore;

MyActions.js

var AppDispatcher = require('../dispatcher/AppDispatcher');
var MyConstants = require('../constants/MyConstants');

var MyActions = {
    setResults: function (values) {
        AppDispatcher.dispatch({
            actionType: MyConstants.SET_RESULTS,
            values:values
        })
    }
};

module.exports = MyActions;

Dispatcher.js

var Dispatcher = require('flux').Dispatcher;

module.exports = new Dispatcher();

MyStoreTest.js

import {
       sinon,
       assert,
       expect
} from '../test_helper';

describe('MyStore', function() {

    var MyStore, AppDispatcher, registerSpy, MyConstants, callback;

beforeEach(() => {
    MyConstants = require('../../../src/js/constants/MyConstants.js');
    MyStore = require("../../../src/js/stores/MyStore.js");
    AppDispatcher = require("../../../src/js/dispatcher/AppDispatcher.js");
    registerSpy = sinon.spy(AppDispatcher, "register");
    AppDispatcher.register(MyStore);
    callback = registerSpy.lastCall.args[0];
});

afterEach(function () {
    registerSpy.restore();
});

it('registers a callback with the dispatcher', function() {
    expect(registerSpy.callCount).to.equal(1);
});

it('initialize with empty results', function() {
   expect(MyStore.getResults().length).to.equal(0);
});

it('fill with some results after action called', function() {
    var someResults = [3, 5, 6, 4];

    var actionSetResults = {
        actionType: MyConstants.SET_RESULTS,
        values: someResults
    };

/* I would like to fire the action and check that after the action 
is called, the value in the store changes. 
I've tried different things but none of them are working. 
probably  something about requiring something or mocking/ not mocking
something important */

   ---> send the action actionSetResults to the store

    var results = MyStore.getResults();
});

Any hint or help? Thanks!

1条回答
The star\"
2楼-- · 2019-04-11 23:56

Small update that might be useful for you: I've managed to get things working after having troubles with the Store's state, which kept being a pain in the butt to reset after each test.

So my current setup involves stubbing the Register method, and spying on the Dispatch in order to run the actions to get them on the store.

I'm using rewire to grab a fresh copy of the Store on each iteration. So on the beforeEach:

TemplateStore = rewire('../../src/js/stores/TemplateStore');
registerSpy = sinon.stub(AppDispatcher, 'register');
dispatchSpy = sinon.spy(AppDispatcher, 'dispatch');
AppDispatcher.register(TemplateStore);
callback = registerSpy.lastCall.args[0];

And on the afterEach:

registerSpy.restore();
dispatchSpy.restore();

So now on your tests you can get data into the stores by calling the Dispatcher directly, like so:

AppDispatcher.dispatch(actionGetter(data));

So far this has proven to work well!

查看更多
登录 后发表回答