
Easy to setup and use - 3 lines of configuration and you can test your single page application like it's really connected to an API / Writes to files etc.
Install side-effect-js from npm : npm install side-effect-js --save
Create side effects file - the name is not important and export an array of side effects:
//side-effects-my-app.js
import SideEffectJS from 'side-effect-js';
var newConsoleEffect = SideEffectJS.CreateEffect('console-effect',
() => { console.log("this is the real x"); },
() => { console.log("x simulate"); }
);
var fetchEffect = SideEffectJS.CreateEffect('fetch-effect',
() => { return fetch('http://www.google.com'); },
() => {
return new Promise(resolve => setTimeout(() => resolve("google test"), 2000));
}
);
export default [newConsoleEffect, fetchEffect];
Note: side effect is an object that must contain: id: string, run: func, simulate: func - id is unique, defining duplicate ids will throw an error SideffectsJS load failed, Found duplicate id in effects:$id on load.
On the root of your app - load all side effects to SideEffectJS:
//App.js or index.js
import sideEffects from './side-effects-my-app.js'
import SideEffectJS from 'side-effect-js';
SideEffectJS.Load(sideEffects);
When you want to use the simulate effect - just add after SideEffectJS.Load this line: SideEffectJS.UseSimulator();
Don't use SideEffectJS.UseSimulator() on production.
Old way (changing code):*
In versions previous to 2.0.0 when you wanted to use the mock side effects you should call SideEffectJS.UseSimulator(); in your code.
You can still do it - but then you need to change this line all the time.
New way (use process.env):*
All you need to do is to initiate SIMULATE_SIDE_EFFECTS=1 and you will get the mock effects.
For example instead of using: node index.js run: SIMULATE_SIDE_EFFECTS=1 node index.js.
For react applications using CRA (create react app) - you can use REACT_APP_SIMULATE_SIDE_EFFECTS=1 in the .env files.
Read more on Create React App .env:
https://create-react-app.dev/docs/adding-custom-environment-variables/
import SideEffectJS from 'side-effect-js';
var effect = SideEffectJS.Get('fetch-effect');
effect().then(x => console.log(x));
Almost any application has side effects:
In order to mock those I/O operations - you need to change your code frequently - means you should replace those I/O with some "stub" code.
So - what can we do better?
Write all side effects in some aggregated place and load real / stub behaviour on run time.
Let's assume we are using redux-thunk or redux-saga and we need to fetch some data. What will we do with this data? save it to the state - and baiscally it will cause the UI to re-render and display something.
So instead of using this example thunk we will use the side-effects approach:
//some-redux-thunk-example
const myThunk = (username, password) => {
dispatch('LOGIN_STARTED');
// I.O operation
fetch('myapi.com/login',
{
username:username,
password:password
})
.then(token => dispatch('LOGIN_SUCCESS', token)
.catch(err => dispatch('LOGIN_FAILED', err);
}
This is how it will look when using Side Effect JS:
//some-redux-thunk-example
import SideEffectJS from 'side-effect-js';
const myThunk = (username, password) => {
dispatch('LOGIN_STARTED');
// I.O operation
SideEffectJS.Get('login')(username, password)
.then(token => dispatch('LOGIN_SUCCESS', token)
.catch(err => dispatch('LOGIN_FAILED', err);
}
What are the benefits of this approach?
In the next versions there will be full support for:
V2.1.0: - 04/27/2020
Deprecated (ts only):
For TypeScript only - CreateEffect is deprecated (backward compatible), instead use: CreateEffectTyped.
Typescript usage example:
const effect SideEffectJS.CreateEffectTyped<T,R>(`some-id`, realFunction, mockFunction)
//T - The model that mock and real function gets
//R - The result type of the mock and real function
//Example.ts
import SideEffectJS from '../side-effect-js';
type GetValue = {
username: string,
passowrd: string
}
const exampleFunctionReal = (loginDetails: GetValue): string => {
return "real";
}
const exampleFunctionMock = (loginDetails: GetValue): string => {
return "mock";
}
//Old way of creating effect
const oldEffect = SideEffectJS.CreateEffect('id-old', exampleFunctionReal, exampleFunctionMock);
//New way of creating effect(V2.1.0+) - ensures real effect and mock effect has the same contract
const effect = SideEffectJS.CreateEffectTyped<GetValue, string>('xxx', exampleFunctionReal, exampleFunctionMock);
V2.0.0: - 04/26/2020
Instead of using SideEffectJS.UseSimulator() - which forces you to change code -> use SIMULATE_SIDE_EFFECTS=1 or REACT_APP_SIMULATE_SIDE_EFFECTS=1 for CRA apps.
SideEffectJS.UseSimulator() is still an option but it forces you to change code before merging.
Read more on Create React App .env:
https://create-react-app.dev/docs/adding-custom-environment-variables/
Generated using TypeDoc