Writing Scenarios Overview
Scenarist scenarios are declarative TypeScript objects that describe what mock responses to return. This guide helps you navigate the scenario features and choose the right ones for your tests.
What Scenarios Can Do
Section titled “What Scenarios Can Do”| Feature | What It Enables | When to Use |
|---|---|---|
| Basic Structure | Define mock responses for HTTP requests | Every scenario needs this |
| Request Matching | Return different responses for same URL based on request content | Different responses for different users, tiers, or request data |
| Pattern Matching | Match using regex, contains, startsWith, endsWith | Campaign codes, user agents, email domains, dynamic values |
| Response Sequences | Return different responses on successive calls | Polling, async job status, multi-step workflows |
| Stateful Mocks | Capture data from requests, inject into later responses | Shopping carts, user profiles, accumulated data |
| Default Scenarios | Define baseline mocks, override only what changes | DRY scenarios, avoid duplication |
| Combining Features | Use all features together | Complex realistic workflows |
| TypeScript Patterns | Type-safe scenario definitions | Autocomplete, compile-time errors |
Which Feature Do I Need?
Section titled “Which Feature Do I Need?”Start here: Every scenario needs the Basic Structure - this defines your mocks with method, URL, and response.
Then ask yourself:
“I need different responses for the same URL”
Section titled ““I need different responses for the same URL””Based on request content? Use Request Matching
- Different pricing for premium vs standard users
- Different responses based on API version header
- Different data based on query parameters
Based on how many times it’s called? Use Response Sequences
- Job status: pending → processing → complete
- Polling patterns
- Retry scenarios
”I need to match dynamic values”
Section titled “”I need to match dynamic values””Use Pattern Matching for:
- Campaign codes:
x-campaign: summer-premium-2024 - User agents:
Mobile,Chrome,Safari - Email domains:
@company.com - File extensions:
.pdf,.jpg
”I need responses to reflect earlier requests”
Section titled “”I need responses to reflect earlier requests””Use Stateful Mocks for:
- Shopping cart that accumulates items
- User profile that reflects submitted data
- Session data that persists across requests
”I’m duplicating mocks across scenarios”
Section titled “”I’m duplicating mocks across scenarios””Use Default Scenarios to:
- Define happy path once in ‘default’
- Override only what changes in specialized scenarios
- Keep scenarios DRY
”I need all of the above”
Section titled “”I need all of the above””See Combining Features for examples of using multiple features together.
Quick Example
Section titled “Quick Example”A minimal scenario with all required fields:
import type { ScenaristScenario } from '@scenarist/express-adapter';
export const myScenario: ScenaristScenario = { id: 'my-scenario', // Unique identifier name: 'My Scenario', // Human-readable name description: 'What this scenario tests', mocks: [ { method: 'GET', url: 'https://api.example.com/user', response: { status: 200, body: { id: 1, name: 'Test User' }, }, }, ],};Why Declarative?
Section titled “Why Declarative?”Scenarist enforces declarative patterns - scenarios describe WHAT to return, not HOW to decide. No imperative functions with hidden if/else logic. This leads to:
- Visible intent - Match criteria show what matters
- Composable features - Specificity-based selection, automatic fallback
- Testable scenarios - Can validate statically with TypeScript
Learn more about the philosophy →
Next Steps
Section titled “Next Steps”- Basic Structure → - Start with the fundamentals
- Request Matching → - Different responses for same URL
- Response Sequences → - Polling and async workflows