angular/angular.js · error · Error
Unsatisfied requests: {}
Error message
Unsatisfied requests: {} What it means
verifyNoOutstandingExpectation() runs a digest and then throws 'Unsatisfied requests: ...' listing every expectation created with expect()/expectGET()/... that no actual request matched. It is the standard afterEach assertion that all expected HTTP calls actually happened (with matching method, URL, and data).
Source
Thrown at src/ngMock/angular-mocks.js:2018
/**
* @ngdoc method
* @name $httpBackend#verifyNoOutstandingExpectation
* @description
* Verifies that all of the requests defined via the `expect` api were made. If any of the
* requests were not made, verifyNoOutstandingExpectation throws an exception.
*
* Typically, you would call this method following each test case that asserts requests using an
* "afterEach" clause.
*
* ```js
* afterEach($httpBackend.verifyNoOutstandingExpectation);
* ```
*/
$httpBackend.verifyNoOutstandingExpectation = function(digest) {
if (digest !== false) $rootScope.$digest();
if (expectations.length) {
throw new Error('Unsatisfied requests: ' + expectations.join(', '));
}
};
/**
* @ngdoc method
* @name $httpBackend#verifyNoOutstandingRequest
* @description
* Verifies that there are no outstanding requests that need to be flushed.
*
* Typically, you would call this method following each test case that asserts requests using an
* "afterEach" clause.
*
* ```js
* afterEach($httpBackend.verifyNoOutstandingRequest);
* ```
*/
$httpBackend.verifyNoOutstandingRequest = function(digest) {View on GitHub (pinned to d8f77817eb)
Solutions
- Invoke the code under test that performs the expected request before verification (often the fix is simply calling the controller/service function).
- Align the expectation with the real call: same method, same URL form (query string, leading slash), and matching data.
- For calls that may legitimately not happen, use when() (backend definition) instead of expect() (strict expectation).
- Read the thrown message — it lists each unsatisfied 'METHOD url' expectation, which tells you exactly which call is missing.
Example fix
// before
it('saves', inject(function($httpBackend, $controller) {
$httpBackend.expectPOST('/items', {name: 'a'}).respond(200);
var ctrl = $controller('ItemCtrl'); // constructor does not POST yet
$httpBackend.verifyNoOutstandingExpectation(); // throws: POST /items unsatisfied
}));
// after
it('saves', inject(function($httpBackend, $controller) {
$httpBackend.expectPOST('/items', {name: 'a'}).respond(200);
var ctrl = $controller('ItemCtrl');
ctrl.save({name: 'a'}); // now the POST is issued
$httpBackend.flush();
$httpBackend.verifyNoOutstandingExpectation();
})); Defensive patterns
Strategy: validation
Validate before calling
// Centralize the afterEach contract; expectations that MAY not fire should be when() instead
// beforeEach: $httpBackend.expectGET('/must') for mandatory calls only
afterEach(function() {
$httpBackend.verifyNoOutstandingExpectation();
$httpBackend.verifyNoOutstandingRequest();
}); Try / catch
// Produce a clearer failure with the spec name plus the unsatisfied list
try {
$httpBackend.verifyNoOutstandingExpectation();
} catch (e) {
if (/^Unsatisfied requests:/.test(e.message)) {
throw new Error(specName + ' never issued:\n' + e.message);
}
throw e;
} Prevention
- Invoke the code under test before the afterEach verification runs.
- Match method, URL (query strings, leading slash), and body exactly in expectations.
- Use when() for optional calls; reserve expect() for calls that must happen.
When it happens
Trigger: expectGET('/api/x').respond(...) was declared but the code never issued that request; the request used a different method/URL/data so it never matched (which typically surfaces earlier as 'Unexpected request' during flush); the request is conditional (feature flag, guard clause) and the test's inputs took the other branch; the triggering function was never called.
Common situations: afterEach($httpBackend.verifyNoOutstandingExpectation) per the ngMock docs; a controller method tested for the success path while the request lives in the error path; URL mismatch from query strings or a missing/extra leading slash; body data not matching because serialization produced a JSON string the expectation does not deep-equal.
Related errors
- No pending request to flush !
- No more pending request to flush !
- Unflushed requests: {} {}
- No deferred tasks to be flushed
- Deferred tasks to flush ({}): {}
AI-assisted analysis of angular/angular.js@d8f77817eb (2026-08-21).
Data as JSON: /api/errors/a72a611f9cb771e9.
Report an issue: GitHub.