{"id":18818,"library":"spy-middleware","title":"spy-middleware","description":"spy-middleware is a Redux middleware for spying on dispatched actions in tests. Version 1.2.2 is the latest stable release. It provides methods to retrieve dispatched actions, query for specific actions, and await actions that have been dispatched or will be dispatched. Unlike simple action loggers, it supports promise-based waiting for actions (until/untilNext), which integrates well with async test patterns. Ideal for integration testing of Redux stores where you need to assert on action sequences or wait for asynchronous side effects.","status":"active","version":"1.2.2","language":"javascript","source_language":"en","source_url":"https://github.com/drpicox/spy-middleware","tags":["javascript","redux","middleware","createStore","spy","testing","applyMiddleware"],"install":[{"cmd":"npm install spy-middleware","lang":"bash","label":"npm"},{"cmd":"yarn add spy-middleware","lang":"bash","label":"yarn"},{"cmd":"pnpm add spy-middleware","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency required for middleware usage with createStore and applyMiddleware","package":"redux","optional":false}],"imports":[{"note":"Package is ESM-only; CommonJS require yields module.exports which is not the default export directly. Use named import or default import as shown.","wrong":"const makeSpyMiddleware = require('spy-middleware')","symbol":"makeSpyMiddleware","correct":"import makeSpyMiddleware from 'spy-middleware'"},{"note":"The package exports a default function; named import will not work.","wrong":"import { makeSpyMiddleware } from 'spy-middleware'","symbol":"default export","correct":"import makeSpyMiddleware from 'spy-middleware'"},{"note":"Instance methods are available on the returned middleware object after creation, but you must apply it via applyMiddleware to a store for it to record actions.","wrong":"makeSpyMiddleware().getActions()","symbol":"spy middleware instance methods","correct":"const spyMiddleware = makeSpyMiddleware(); spyMiddleware.getActions(); spyMiddleware.untilNext(); etc."}],"quickstart":{"code":"import { createStore, applyMiddleware } from 'redux';\nimport makeSpyMiddleware from 'spy-middleware';\n\nconst spyMiddleware = makeSpyMiddleware();\nconst reducer = (state = [], action) => [...state, action.type];\nconst store = createStore(reducer, applyMiddleware(spyMiddleware));\n\nstore.dispatch({ type: 'FIRST' });\nstore.dispatch({ type: 'SECOND' });\n\nconsole.log(spyMiddleware.getActions()); // [{ type: 'FIRST' }, { type: 'SECOND' }]\n\n// Wait for a specific action\nsetTimeout(() => store.dispatch({ type: 'THIRD' }), 10);\nspyMiddleware.untilNext('THIRD').then(action => console.log('Got:', action));","lang":"javascript","description":"Shows how to create spy middleware, apply to store, dispatch actions, get all actions, and wait for an action using untilNext."},"warnings":[{"fix":"Apply spyMiddleware as the last argument to applyMiddleware: applyMiddleware(otherMiddleware, spyMiddleware)","message":"The spy middleware must be placed last in the middleware chain to capture all actions after other middleware process them.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Assign the result to a variable if you need to manipulate it.","message":"The getActions() method returns a new array each time, not a live reference; mutations to the returned array do not affect the recorded actions.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use spyMiddleware.until() if you want to match actions that may have already been dispatched.","message":"untilNext() resolves only if the matching action is dispatched after the call; if the action already happened, it never resolves. Use until() for matching past actions.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"N/A","message":"None documented. Package is stable with no known deprecations.","severity":"deprecated","affected_versions":">=0.0.0"},{"fix":"Ensure filter functions return a boolean or truthy value.","message":"The condition parameter for getAction and until/untilNext can be a string, RegExp, or function, but undefined return from function does not match.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-25T00:00:00.000Z","next_check":"2026-07-24T00:00:00.000Z","problems":[{"fix":"Use default import: import makeSpyMiddleware from 'spy-middleware'","cause":"Wrong import: used named import {} instead of default import, or used require which gives the module object.","error":"TypeError: makeSpyMiddleware is not a function"},{"fix":"Ensure spyMiddleware is passed to applyMiddleware and that the store is created with that enhancer.","cause":"Spy middleware not applied to store, or applied incorrectly (e.g., not last in chain).","error":"Actions not being recorded"},{"fix":"Use spyMiddleware.until() instead if you expect the action might have already fired.","cause":"The matching action was already dispatched before untilNext was called.","error":"Promise never resolves when using untilNext"},{"fix":"Confirm you have version 1.0.0+ and that you created the middleware: const sm = makeSpyMiddleware(); then use sm.untilNext().","cause":"Using an old version or incorrect object; ensure you are calling untilNext on the result of makeSpyMiddleware().","error":"spyMiddleware.untilNext is not a function"}],"ecosystem":"npm","meta_description":null,"install_score":null,"install_tag":null,"quickstart_score":null,"quickstart_tag":null}