Skip to content

Requests ​

Inspect what your code actually sent.

HttpMock.requestsTo() counts the callouts made to an endpoint, and hands you the HttpRequest objects themselves — so you can assert on the body, the headers, or the method your code built.

Counting ​

apex
Assert.areEqual(3, HttpMock.requestsTo('/api/users').all(), 'Three requests should be made');
Assert.areEqual(1, HttpMock.requestsTo('/api/users').get(), 'One GET request should be made');
Assert.areEqual(2, HttpMock.requestsTo('/api/users').post(), 'Two POST requests should be made');

The Last Request ​

The common case: one callout, and you want to know what went out.

apex
new HttpMock()
  .whenPostOn('/api/users')
  .statusCodeCreated()
  .mock();

Test.startTest();
new UserApi().createUser('Jane');
Test.stopTest();

HttpRequest sent = HttpMock.requestsTo('/api/users').last();

Assert.areEqual('{"name":"Jane"}', sent.getBody(), 'Body should carry the name');
Assert.areEqual('POST', sent.getMethod(), 'Method should be POST');
Assert.areEqual('application/json', sent.getHeader('Content-Type'), 'Content-Type should be application/json');

last() returns null when no request was made to the endpoint.

Every Request ​

captured() returns the requests in the order they were made — useful when your code batches, paginates, or retries.

apex
new HttpMock()
  .whenPostOn('/api/contacts').statusCodeOk()
  .whenPostOn('/api/contacts').statusCodeOk()
  .mock();

Test.startTest();
new ContactApi().upload(contacts);
Test.stopTest();

List<HttpRequest> sent = HttpMock.requestsTo('/api/contacts').captured();

Assert.areEqual(2, sent.size(), 'The upload should be split into two batches');
Assert.areEqual(300, batchSizeOf(sent[0]), 'First batch should be full');
Assert.areEqual(50, batchSizeOf(sent[1]), 'Second batch should carry the remainder');

This is what catches a payload that is built wrong: the callout still returns 200, the code under test still reports success, and only the sent body says the shape was off.

Filtering by Method ​

When several verbs hit the same endpoint, every lookup has a per-method variant: capturedGets() … capturedHeads() for the full list, lastGet() … lastHead() for the most recent one.

apex
new HttpMock()
  .whenGetOn('/api/users').statusCodeOk()
  .whenPostOn('/api/users').statusCodeCreated()
  .mock();

Test.startTest();
new UserApi().syncUsers(); // fetches with GET, then pushes two batches with POST
Test.stopTest();

List<HttpRequest> pushes = HttpMock.requestsTo('/api/users').capturedPosts();

Assert.areEqual(2, pushes.size(), 'The push should be split into two batches');
Assert.areEqual('{"name":"Jane"}', HttpMock.requestsTo('/api/users').lastPost().getBody(), 'Last POST should carry the final payload');

Like their unfiltered counterparts, the captured*() variants return an empty list and the last*() variants return null when no request with that method was made.

Failed Callouts ​

A callout that throws is still recorded — it was sent. See Exceptions.

Reference ​

MethodReturns
all()Number of requests, all methods
get() post() put() patch() deletex() trace() head()Number of requests for that method
captured()List<HttpRequest>, in the order sent
capturedGets() capturedPosts() capturedPuts() capturedPatches() capturedDeletes() capturedTraces() capturedHeads()List<HttpRequest> for that method, in the order sent
last()The most recent HttpRequest, or null
lastGet() lastPost() lastPut() lastPatch() lastDelete() lastTrace() lastHead()The most recent HttpRequest for that method, or null