I am writing mocha tests against a Reflux store, to validate that an action causes the state within a store to change. The scaled-down version of the code is given below:
Store:
var AppStore = Reflux.createStore({
init: function () {
this.foo = false;
},
listenables: [AppActions],
onFooAction: function() {
this.foo = !this.foo;
this.trigger({action: "foo-ed"});
};
});
Action:
var AppActions = Reflux.createActions([
"fooAction"
]);
Test:
it("toggles foo", function () {
expect(AppStore.foo).to.equal(false);
AppStore.listenables[0].fooAction();
expect(AppStore.foo).to.equal(true);
});
However, the second assertion (expect(AppStore.foo).to.equal(true);
) fails saying that foo
is still false.
By performing a console.log
within the onFooAction
method, I've verified that the method is actually triggered and this.foo
is getting toggled.
Is there anything fundamental that I am missing here: conceptually or otherwise? I sincerely hope that it is not a timing issue!
Actions emit events to which the stores listen. Basically, your test is just running too quickly.
Usually, in my tests, I assume that Reflux is going to do what it does correctly, and I call the listener function directly. You'd want to add a few more assertions to make sure that Reflux is wired up correctly.
it("is configured", function () {
expect(AppStore.listenables).to.include(AppActions);
expect(AppActions.fooAction).to.be.a('function');
});
it("toggles foo", function () {
expect(AppStore.foo).to.equal(false);
AppStore.onFooAction();
expect(AppStore.foo).to.equal(true);
});
Another way you could test this is with a timeout, but I feel dirty when I put timeouts inside tests.
it("toggles foo", function (done) {
expect(AppStore.foo).to.equal(false);
AppStore.listenables[0].fooAction();
setTimeout(function () {
try {
expect(AppStore.foo).to.equal(true);
done();
} catch (e) {
done(e);
}
}, 15);
});