apex-http-callout-mocking
HttpCalloutMock for Apex tests: HttpCalloutMock interface, StaticResourceCalloutMock, MultiStaticResourceCalloutMock, Test.setMock, multi-call mocks for pagination, error-path mocks. NOT for the callout code itself (use callouts-and-http-integrations). NOT for WSDL callouts (use apex-wsdl2apex-patterns).
Best use case
apex-http-callout-mocking is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
HttpCalloutMock for Apex tests: HttpCalloutMock interface, StaticResourceCalloutMock, MultiStaticResourceCalloutMock, Test.setMock, multi-call mocks for pagination, error-path mocks. NOT for the callout code itself (use callouts-and-http-integrations). NOT for WSDL callouts (use apex-wsdl2apex-patterns).
Teams using apex-http-callout-mocking should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/apex-http-callout-mocking/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How apex-http-callout-mocking Compares
| Feature / Agent | apex-http-callout-mocking | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
HttpCalloutMock for Apex tests: HttpCalloutMock interface, StaticResourceCalloutMock, MultiStaticResourceCalloutMock, Test.setMock, multi-call mocks for pagination, error-path mocks. NOT for the callout code itself (use callouts-and-http-integrations). NOT for WSDL callouts (use apex-wsdl2apex-patterns).
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# Apex HTTP Callout Mocking
Activate when testing Apex code that makes HTTP callouts. Apex disallows real HTTP during tests; you MUST supply a mock via `Test.setMock`. The default single-response mock covers simple cases, but pagination, retry, and multi-endpoint flows require stateful mocks.
## Before Starting
- **Enumerate callouts.** How many requests, which endpoints, which status-code paths?
- **Pick the mock shape.** Single response → `StaticResourceCalloutMock`. Multiple responses → custom `HttpCalloutMock`. Per-endpoint routing → `MultiStaticResourceCalloutMock`.
- **Load-bearing response body content.** Store JSON in a `StaticResource` instead of inline strings to keep tests reviewable.
## Core Concepts
### HttpCalloutMock interface
```
public class MyMock implements HttpCalloutMock {
public HttpResponse respond(HttpRequest req) {
HttpResponse r = new HttpResponse();
r.setStatusCode(200);
r.setBody('{"ok":true}');
return r;
}
}
```
Register via `Test.setMock(HttpCalloutMock.class, new MyMock());` before the code-under-test runs.
### StaticResourceCalloutMock
```
StaticResourceCalloutMock m = new StaticResourceCalloutMock();
m.setStaticResource('OrderResponse'); // StaticResource with JSON body
m.setStatusCode(200);
m.setHeader('Content-Type', 'application/json');
Test.setMock(HttpCalloutMock.class, m);
```
Stores the response body in metadata; best for large fixtures.
### MultiStaticResourceCalloutMock
```
MultiStaticResourceCalloutMock m = new MultiStaticResourceCalloutMock();
m.setStaticResource('https://api/x/orders', 'OrdersResponse');
m.setStaticResource('https://api/x/accounts', 'AccountsResponse');
m.setStatusCode(200);
m.setHeader('Content-Type', 'application/json');
Test.setMock(HttpCalloutMock.class, m);
```
Routes by request endpoint; single mock handles multiple distinct endpoints.
### Multi-call stateful mock (pagination)
```
public class PageMock implements HttpCalloutMock {
private Integer call = 0;
private List<String> bodies;
public PageMock(List<String> bodies) { this.bodies = bodies; }
public HttpResponse respond(HttpRequest req) {
HttpResponse r = new HttpResponse();
r.setStatusCode(200);
r.setBody(call < bodies.size() ? bodies[call++] : '{}');
return r;
}
}
```
Required when a single endpoint is called multiple times and each response differs (pagination, retry).
### Uncommitted-work-pending error
If DML precedes a callout in the same transaction, Salesforce throws `CalloutException: You have uncommitted work pending`. Cannot be "fixed" in a mock — refactor to Queueable or call DML AFTER all callouts complete.
## Common Patterns
### Pattern: Error-path test
```
public class ErrorMock implements HttpCalloutMock {
public HttpResponse respond(HttpRequest req) {
HttpResponse r = new HttpResponse();
r.setStatusCode(500);
r.setBody('{"error":"down"}');
return r;
}
}
@IsTest static void testHandlesServerError() {
Test.setMock(HttpCalloutMock.class, new ErrorMock());
Test.startTest();
Boolean result = OrderService.fetch();
Test.stopTest();
System.assertEquals(false, result);
}
```
### Pattern: Endpoint-dispatched mock
```
public class Router implements HttpCalloutMock {
public HttpResponse respond(HttpRequest req) {
HttpResponse r = new HttpResponse();
r.setStatusCode(200);
if (req.getEndpoint().contains('/orders')) r.setBody(ORDERS_JSON);
else if (req.getEndpoint().contains('/auth')) r.setBody(AUTH_JSON);
else r.setStatusCode(404);
return r;
}
}
```
### Pattern: Header assertion
```
public class HeaderMock implements HttpCalloutMock {
public static String capturedAuth;
public HttpResponse respond(HttpRequest req) {
capturedAuth = req.getHeader('Authorization');
// ... return response
}
}
// In test: assert HeaderMock.capturedAuth == 'Bearer expected_token'
```
## Decision Guidance
| Situation | Mock |
|---|---|
| One endpoint, one response | `StaticResourceCalloutMock` |
| Many endpoints, one each | `MultiStaticResourceCalloutMock` |
| One endpoint, multiple calls returning different bodies | Custom `HttpCalloutMock` with call counter |
| Error-path testing | Custom mock returning non-2xx |
| Assert on request headers/body | Custom mock capturing into static fields |
## Recommended Workflow
1. Identify every callout the test exercises (endpoint, verb, count).
2. Store large JSON fixtures as `StaticResource` files.
3. Choose mock type per the decision table.
4. For multi-call: implement counter-based `HttpCalloutMock`.
5. Register via `Test.setMock` BEFORE the code-under-test is invoked.
6. For error paths, add a parallel test with an error-returning mock.
7. Assert on side-effects AND, where relevant, on captured request fields.
## Review Checklist
- [ ] `Test.setMock` called before the code-under-test runs
- [ ] Multi-call scenarios use a stateful custom mock (not a single-response mock reused)
- [ ] Error-path test present (non-2xx status)
- [ ] Large fixtures in `StaticResource`, not inline
- [ ] Test does no DML between callouts that triggers "uncommitted work pending"
- [ ] Request-level assertions (headers/body) where security/auth matters
## Salesforce-Specific Gotchas
1. **`Test.setMock` must be called before any callout in the transaction.** Calling it after the first callout is ignored.
2. **You cannot perform a real callout in a test even with no `setMock` — it throws.** Forgetting to set a mock yields a test failure, not a skip.
3. **`HttpCalloutMock` respond method runs within the test's governor context** — don't do heavy DML inside it.
4. **`MultiStaticResourceCalloutMock` matches the endpoint string literally** — query parameters in the request but not the mock registration cause misses.
## Output Artifacts
| Artifact | Description |
|---|---|
| Custom `HttpCalloutMock` | Stateful mock for multi-call tests |
| `StaticResource` JSON fixtures | Reviewable response bodies |
| Error-path mocks | 4xx/5xx responses |
| Header-capture mock | Assertion helper for request validation |
## Related Skills
- `apex/apex-test-setup-patterns` — test structure + startTest/stopTest
- `apex/callouts-and-http-integrations` — the callout code itself
- `integration/rest-api-pagination-patterns` — pagination tests need multi-call mocksRelated Skills
apex-managed-sharing-patterns
Grant row-level access programmatically via __Share records when declarative sharing rules cannot express the policy. NOT for OWD, role hierarchy, or criteria-based sharing rule design.
lwc-imperative-apex
Call Apex methods imperatively from LWC — on button click, lifecycle hooks, or conditional logic. Covers import syntax, cacheable vs non-cacheable, async/await patterns, error handling, loading states, and Promise.all. NOT for wire service (use wire-service-patterns) and NOT for testing Apex mocks (use lwc-testing).
mutual-tls-callouts
Configure mTLS for Apex callouts using Named Credentials with client certificate authentication. NOT for standard TLS or API key auth.
dataweave-for-apex
Use when transforming structured data inside Apex — CSV → JSON, XML → SObject list, JSON → flattened CSV, or schema-mapping a third-party payload to a Salesforce model — and the existing options (`JSON.deserialize`, `Dom.Document`, hand-written loops) are getting unwieldy. Triggers: 'apex transform csv json xml without external library', 'system.dataweave script', 'salesforce native dataweave apex execute', 'transform xml to sobject apex no mulesoft', 'json reshape salesforce apex script'. NOT for MuleSoft Anypoint DataWeave running off-platform (use mulesoft-anypoint-architecture), NOT for Apex JSON serialization basics (use apex-json-serialization), NOT for Bulk API CSV ingest (use bulk-api-2-patterns).
callout-limits-and-async-patterns
Use when designing or troubleshooting Apex callouts that approach governor limits: choosing between synchronous callouts, @future, Queueable, Continuation, or async chaining strategies. NOT for HTTP request construction or Named Credential setup (use named-credentials-setup).
flow-invocable-from-apex
Author @InvocableMethod Apex classes that Flow can call as Actions. Design the input / output variable contract, bulk semantics (one list in, one list out), null handling, and error surfacing. Also covers the inverse direction: calling a flow from Apex via Flow.Interview. NOT for general Apex authoring (use apex-service-selector-domain). NOT for REST-exposed Apex (use apex-rest-resource-patterns).
flow-http-callout-action
Call external HTTP APIs directly from Flow using HTTP Callout actions (no Apex), handling auth, schema, and errors. NOT for complex Apex-based integration logic.
flow-apex-defined-types
Design and use Apex-Defined Types as Flow variables for structured non-sObject data (HTTP callout payloads, External Service responses, complex configuration). Trigger keywords: apex-defined type, flow variable, @AuraEnabled class, flow http callout response. Does NOT cover building HTTP Callout Actions themselves, External Services schema, or raw Apex invocable methods.
scheduled-apex-failure-detection-and-monitoring
Use when nightly batch / scheduled Apex jobs are failing without anyone noticing — covers why uncaught exceptions in `execute()` go to the debug log instead of email, how to query `AsyncApexJob` for `Status`, `NumberOfErrors`, and `ExtendedStatus`, when to implement `Database.RaisesPlatformEvents` so the platform publishes `BatchApexErrorEvent` on uncaught failures, how to subscribe to that event with an Apex trigger and notify operators, and how to layer a custom watcher schedule on top so silent-failure modes (job that never started, scheduled class deleted, queue stuck on `Queued`) still surface. Triggers: 'nightly batch failed at 2am with no notification', 'how do we know if a scheduled apex job is failing', 'BatchApexErrorEvent vs custom retry logic', 'Setup Apex Jobs only shows last 7 days, where else can I look', 'job is stuck in queued status nobody noticed for a week'. NOT for general Apex exception handling patterns (use apex/apex-exception-handling-and-logging), NOT for Batch Apex authoring or chunking strategy (use apex/batch-apex-design), NOT for Setup → Apex Jobs UI walkthrough as an admin task (use admin/batch-job-scheduling-and-monitoring), NOT for retry logic itself (use apex/scheduled-apex-retry-patterns once authored).
platform-events-apex
Use when publishing or subscribing to Salesforce Platform Events from Apex, comparing Platform Events with Change Data Capture, or designing event-triggered error handling and monitoring. Triggers: 'EventBus.publish', 'platform event trigger', 'CDC vs Platform Events', 'replay ID', 'high-volume event'. NOT for Flow-only publish/subscribe automation.
health-cloud-apex-extensions
Use this skill when extending Health Cloud via Apex: implementing HealthCloudGA managed-package interfaces, automating care plan lifecycle hooks, processing referrals using Industries Common Components invocable actions, or enforcing HIPAA-compliant logging governance for clinical Apex code. Trigger keywords: CarePlanProcessorCallback, HealthCloudGA namespace, ReferralRequest, ReferralResponse, care plan invocable actions, clinical Apex extension, Health Cloud Apex API. NOT for standard Apex triggers or generic Apex development unrelated to Health Cloud managed-package extension points.
fsl-apex-extensions
Use when writing Apex that calls Field Service Lightning scheduling APIs — AppointmentBookingService, ScheduleService, GradeSlotsService, or OAAS — to book, schedule, grade, or optimize service appointments programmatically. Trigger keywords: FSL Apex namespace, GetSlots, schedule service appointment via code, appointment booking API, FSL optimization API. NOT for standard Apex patterns unrelated to FSL, admin-level scheduling policy configuration, or declarative FSL scheduling.