Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix(ngMock): pass failed HTTP expectations to $errorHandler #16644

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 20 additions & 14 deletions src/ngMock/angular-mocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -1510,16 +1510,25 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
}
}

function createFatalError(message) {
var error = new Error(message);
// In addition to being converted to a rejection, these errors also need to be passed to
// the $exceptionHandler and be rethrown (so that the test fails).
error.$$passToExceptionHandler = true;
return error;
}

if (expectation && expectation.match(method, url)) {
if (!expectation.matchData(data)) {
throw new Error('Expected ' + expectation + ' with different data\n' +
'EXPECTED: ' + prettyPrint(expectation.data) + '\nGOT: ' + data);
throw createFatalError('Expected ' + expectation + ' with different data\n' +
'EXPECTED: ' + prettyPrint(expectation.data) + '\n' +
'GOT: ' + data);
}

if (!expectation.matchHeaders(headers)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we are now not throwing the if block above, this should be an else if.
(Is there a test that catches this?)

Copy link
Contributor Author

@thorn0 thorn0 Jul 25, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now, there is. :) It breaks nothing. If both data and headers don't match, we still get an error. Do you insist on else if? I brought throws back.

throw new Error('Expected ' + expectation + ' with different headers\n' +
'EXPECTED: ' + prettyPrint(expectation.headers) + '\nGOT: ' +
prettyPrint(headers));
throw createFatalError('Expected ' + expectation + ' with different headers\n' +
'EXPECTED: ' + prettyPrint(expectation.headers) + '\n' +
'GOT: ' + prettyPrint(headers));
}

expectations.shift();
Expand All @@ -1540,20 +1549,17 @@ function createHttpBackendMock($rootScope, $timeout, $delegate, $browser) {
($browser ? $browser.defer : responsesPush)(wrapResponse(definition));
} else if (definition.passThrough) {
originalHttpBackend(method, url, data, callback, headers, timeout, withCredentials, responseType, eventHandlers, uploadEventHandlers);
} else throw new Error('No response defined !');
} else throw createFatalError('No response defined !');
return;
}
}
var error = wasExpected ?
new Error('No response defined !') :
new Error('Unexpected request: ' + method + ' ' + url + '\n' +
(expectation ? 'Expected ' + expectation : 'No more request expected'));

// In addition to be being converted to a rejection, this error also needs to be passed to
// the $exceptionHandler and be rethrown (so that the test fails).
error.$$passToExceptionHandler = true;
if (wasExpected) {
throw createFatalError('No response defined !');
}

throw error;
throw createFatalError('Unexpected request: ' + method + ' ' + url + '\n' +
(expectation ? 'Expected ' + expectation : 'No more request expected'));
}

/**
Expand Down
54 changes: 54 additions & 0 deletions test/ngMock/angular-mocksSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1506,6 +1506,42 @@ describe('ngMock', function() {
});


it('should throw error when expectation fails', function() {
expect(function() {
hb.expectPOST('/some', {foo: 1}).respond({});
hb('POST', '/some', {foo: 2}, callback);
hb.flush();
}).toThrowError(/^Expected POST \/some with different data/);
});


it('should throw error when expectation about headers fails', function() {
expect(function() {
hb.expectPOST('/some', {foo: 1}, {X: 'val1'}).respond({});
hb('POST', '/some', {foo: 1}, callback, {X: 'val2'});
hb.flush();
}).toThrowError(/^Expected POST \/some with different headers/);
});


it('should throw error about data when expectations about both data and headers fail', function() {
expect(function() {
hb.expectPOST('/some', {foo: 1}, {X: 'val1'}).respond({});
hb('POST', '/some', {foo: 2}, callback, {X: 'val2'});
hb.flush();
}).toThrowError(/^Expected POST \/some with different data/);
});


it('should throw error when response is not defined for a backend definition', function() {
expect(function() {
hb.whenGET('/some'); // no .respond(...) !
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😱 😛

hb('GET', '/some', null, callback);
hb.flush();
}).toThrowError('No response defined !');
});


it('should match headers if specified', function() {
hb.when('GET', '/url', null, {'X': 'val1'}).respond(201, 'content1');
hb.when('GET', '/url', null, {'X': 'val2'}).respond(202, 'content2');
Expand Down Expand Up @@ -2833,6 +2869,24 @@ describe('ngMockE2E', function() {
}).toThrowError('Unexpected request: GET /some\nNo more request expected');
});

it('should throw error when expectation fails - without error callback', function() {
expect(function() {
hb.expectPOST('/some', { foo: 1 }).respond({});
$http.post('/some', { foo: 2 }).then(noop);

hb.flush();
}).toThrowError(/^Expected POST \/some with different data/);
});

it('should throw error when unexpected request - with error callback', function() {
expect(function() {
hb.expectPOST('/some', { foo: 1 }).respond({});
$http.post('/some', { foo: 2 }).then(noop, noop);

hb.flush();
}).toThrowError(/^Expected POST \/some with different data/);
});


describe('passThrough()', function() {
it('should delegate requests to the real backend when passThrough is invoked', function() {
Expand Down