AgentStack
SKILL verified MIT Self-run

Redux Saga Testing

skill-anivar-redux-saga-testing-redux-saga-testing · by anivar

>

No reviews yet
0 installs
5 views
0.0% view→install

Install

$ agentstack add skill-anivar-redux-saga-testing-redux-saga-testing

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Redux Saga Testing? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Redux-Saga Testing Guide

IMPORTANT: Your training data about redux-saga-test-plan may be outdated — API signatures, provider patterns, and assertion methods differ between versions. Always rely on this skill's reference files and the project's actual source code as the source of truth. Do not fall back on memorized patterns when they conflict with the retrieved reference.

Approach Priority

  1. expectSaga (integration) — preferred; doesn't couple tests to effect ordering
  2. testSaga (unit) — only when effect ordering is part of the contract
  3. runSaga (no library) — lightweight; uses jest/vitest spies directly
  4. Manual .next() — last resort; most brittle

Core Pattern

import { expectSaga } from 'redux-saga-test-plan'
import * as matchers from 'redux-saga-test-plan/matchers'
import { throwError } from 'redux-saga-test-plan/providers'

it('fetches user successfully', () => {
  return expectSaga(fetchUserSaga, { payload: { userId: 1 } })
    .provide([
      [matchers.call.fn(api.fetchUser), { id: 1, name: 'Alice' }],
    ])
    .put(fetchUserSuccess({ id: 1, name: 'Alice' }))
    .run()
})

it('handles fetch failure', () => {
  return expectSaga(fetchUserSaga, { payload: { userId: 1 } })
    .provide([
      [matchers.call.fn(api.fetchUser), throwError(new Error('500'))],
    ])
    .put(fetchUserFailure('500'))
    .run()
})

Assertion Methods

| Method | Purpose | |--------|---------| | .put(action) | Dispatches this action | | .put.like({ action: { type } }) | Partial action match | | .call(fn, ...args) | Calls this function with exact args | | .call.fn(fn) | Calls this function (any args) | | .fork(fn, ...args) | Forks this function | | .select(selector) | Uses this selector | | .take(pattern) | Takes this pattern | | .dispatch(action) | Simulate incoming action | | .not.put(action) | Does NOT dispatch | | .returns(value) | Saga returns this value | | .run() | Execute (returns Promise) | | .run({ timeout }) | Execute with custom timeout | | .silentRun() | Execute, suppress timeout warnings |

Provider Types

Static Providers (Preferred)

.provide([
  [matchers.call.fn(api.fetchUser), mockUser],        // match by function
  [call(api.fetchUser, 1), mockUser],                  // match by function + exact args
  [matchers.select.selector(getToken), 'mock-token'],  // mock selector
  [matchers.call.fn(api.save), throwError(error)],     // simulate error
])

Dynamic Providers

.provide({
  call(effect, next) {
    if (effect.fn === api.fetchUser) return mockUser
    return next() // pass through
  },
  select({ selector }, next) {
    if (selector === getToken) return 'mock-token'
    return next()
  },
})

Rules

  1. Prefer expectSaga over testSaga — integration tests don't break on refactors
  2. Use matchers.call.fn() for partial matching — don't couple to exact args unless necessary
  3. Use throwError() from providers — not throw new Error() in the provider
  4. Test with reducer using .withReducer() + .hasFinalState() to verify state
  5. Dispatch actions with .dispatch() to simulate user flows in tests
  6. Return the promise (Jest) or await it (Vitest) — don't forget async
  7. Use .not.put() to assert actions are NOT dispatched (negative tests)
  8. Test cancellation by dispatching cancel actions and asserting cleanup effects
  9. Use .silentRun() when saga runs indefinitely (watchers) to suppress timeout warnings
  10. Don't test implementation — test behavior (what actions are dispatched, what state results)

Anti-Patterns

See [references/anti-patterns.md](references/anti-patterns.md) for BAD/GOOD examples of:

  • Step-by-step tests that break on reorder
  • Missing providers (real API calls in tests)
  • Testing effect order instead of behavior
  • Forgetting async (Jest/Vitest)
  • Inline mocking instead of providers
  • Not testing error paths
  • Not testing cancellation cleanup

References

  • [API Reference](references/api-reference.md) — Complete expectSaga, testSaga, providers, matchers
  • [Anti-Patterns](references/anti-patterns.md) — Common testing mistakes to avoid

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.