jeffbski / redux-logic

Redux middleware for organizing all your business logic. Intercept actions and perform async processing.
MIT License
1.81k stars 107 forks source link

RFC: redux-logic-test - helper utilities #25

Open jeffbski opened 7 years ago

jeffbski commented 7 years ago

I'm thinking it might be nice to create a separate helper project which will help make it easy to create mock stores for integration level tests. It would basically let you setup your test store in one line of code hooking up as much or as little as you want to specify.

Then it provides a few nice methods to facilitate testing like knowing when the logic is complete and then being able to see an array list of actions that were dispatched.

Let me know what you think. I want it to be simple but yet including the right things to make testing easy.

import { createMockStore } from 'redux-logic-test';

// specify as much as necessary for your particular test
const store = createMockStore({
  initialState: optionalObject,
  reducer: optionalFn, // default: identity reducer fn(state, action) { return state; }
  logic: optionalLogic, // default: [] - used for the logicMiddleware that is created
  injectedDeps: optionalObject, // default {} - used for the logicMiddleware that is created
  middleware: optionalArr // other mw, exclude logicMiddleware from this array
});
store.dispatch(...) // use as necessary for your test
store.whenComplete(fn) - shorthand for store.logicMiddleware.whenComplete(fn) - when all inflight logic has all completed calls fn and returns promise
store.actions - the actions dispatched, use store.resetActions() to clear
store.resetActions() - clear store.actions
store.logicMiddlware // access logicMiddleware automatically created from logic/injectedDeps props
// allows you to use store.logicMiddleware.addLogic, mergeNewLogic, replaceLogic, whenComplete, monitor$

// So a test might look something like

const store = createMockStore({
  initialState: { foo: 42 },
  logic: [ fooLogic, barLogic ], // logicMiddleware will be created for this logic and injectedDeps
  injectedDeps: { api: myAPI }
});

store.dispatch({ type: FOO });
store.dispatch({ type: BAR });
store.whenComplete(() => { // when logic is finished
  expect(store.actions).toEqual([ // check the actions that were dispatched
    { type: FOO },
    { type: BAR },
    { type: FOO_SUCCESS, payload: [] },
    { type: BAR_SUCCESS, payload: {} }
  ]);
});

I didn't require a reducer so I didn't need to create one, but if you test needs that you can supply one.

I have a gist of the API here

jeffbski commented 7 years ago

I'm thinking this will just live in its own package maybe named redux-logic-test

kopax commented 7 years ago

I agree with most of it. I still wonder how you will do for all cases. I can test it when you'll be ready, please tell me when you got a branch.

jeffbski commented 7 years ago

ok, I'll see if there are any other thoughts or comments and then I'll whip it up and let you give it a spin.

jeffbski commented 7 years ago

I just published redux-logic-test, let me know if you have any questions or run into any problems using it.

https://github.com/jeffbski/redux-logic-test

kopax commented 7 years ago

Thanks for releasing it that fast, I look into this as soon as I have time.

jeffbski commented 7 years ago

You are welcome. Let me know if you run into any questions on use.