ferp-js
Search…
Testing Your Subscriptions

Run it like a Function

Since subscriptions are just functions, you should easily be able to execute them. The signature of every subscription is (...params) => (dispatch) => cleanUpFn, so we know how to get the code to execute, and how to stop it, so what's preventing us from doing that? Let's take this subscription as an example:
mySubscription.js
1
export const mySubscription = (dispatch, delay, onIntervalAction) => dispatch => {
2
const handle = setInterval(dispatch, delay, onIntervalAction);
3
return () => {
4
clearInterval(handle);
5
};
6
};
Copied!
Maybe a test could look something like this:
mySubscription.spec.js
1
import { mySubscription } from './mySubscription.js';
2
import * as sinon from 'sinon';
3
4
describe('mySubscription', () => {
5
it('creates an interval', () => {
6
expect.assertions(1);
7
sinon.spyOn(global, 'setInterval');
8
const dispatch = sinon.fake();
9
const myAction = () => {};
10
11
const cleanup = mySubscription(dispatch, 1000, myAction);
12
expect(global.setInterval.mock.calls).toHaveLength(1);
13
cleanup();
14
expect(dispatch.calledWith, [myAction]);
15
16
setInterval.restore();
17
});
18
});
Copied!

End to End Testing

Calling your subscription in a test can get you fairly far, but the real test is when your application expects some sort of payload from your subscription.
myApplication.spec.js
1
import { app, effects } from 'ferp';
2
3
import { intervalSub } from './intervalSub.js';
4
5
const testify = (expectedActions, done) => (_, actionAnnotation) => {
6
const actionName = expectedActions.unshift();
7
expect(actionAnnotation).toBe(actionName);
8
9
if (expectedActions.length === 0) {
10
return done();
11
}
12
};
13
14
describe('myApplication', () => {
15
it('runs an effect from mySubscription', (done) => {
16
const myAction = state => [false, effects.none()];
17
18
app({
19
init: [true, effects.none()],
20
observe: testify([
21
'ferpAppInitialization', // this is just the action/annotation of `init`
22
'myAction',
23
], done),
24
subscribe: state => [
25
state && [intervalSub, 1000, myAction],
26
],
27
});
28
});
29
});
Copied!
Last modified 2mo ago