Skip to content
Back to skills

Redux Saga Testing

ASecurity

Write tests for Redux Sagas using redux-saga-test-plan, runSaga, and manual generator testing. Covers expectSaga (integration), testSaga (unit), providers, partial matchers, reducer integration, error simulation, and cancellation testing. Works with Jest and Vitest. Triggers on: test files for sagas, redux-saga-test-plan imports, mentions of \"test saga\", \"saga test\", \"expectSaga\", \"testSaga\", or \"redux-saga-test-plan\".

  • 33 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 5, 2026
testingjavascriptgojavatestingapi

Works with

  • api

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 5, 2026

npx -y skills add dvcrn/openclaw-skills-marketplace --skill redux-saga-testing --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Redux Saga Testing?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Redux Saga Testing
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/dvcrn-redux-saga-testing/badge)](https://www.skillsdirectory.com/skills/dvcrn-redux-saga-testing)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: redux-saga-testing
description: "Write tests for Redux Sagas using redux-saga-test-plan, runSaga, and manual generator testing. Covers expectSaga (integration), testSaga (unit), providers, partial matchers, reducer integration, error simulation, and cancellation testing. Works with Jest and Vitest. Triggers on: test files for sagas, redux-saga-test-plan imports, mentions of \"test saga\", \"saga test\", \"expectSaga\", \"testSaga\", or \"redux-saga-test-plan\"."
---

# 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

```javascript
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)

```javascript
.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

```javascript
.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

Files in this skill

  • README.md3.8 KB
  • SKILL.md4.6 KB
  • references/anti-patterns.md6.5 KB
  • references/api-reference.md11.1 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…