-
Notifications
You must be signed in to change notification settings - Fork 27.5k
feat(ngMocks): add $httpBackend.whenOverride method #16251
feat(ngMocks): add $httpBackend.whenOverride method #16251
Conversation
Cool @szimek - I'll take a look tomorrow |
203f4c5
to
7193eae
Compare
test/ngMock/angular-mocksSpec.js
Outdated
@@ -1106,6 +1116,22 @@ describe('ngMock', function() { | |||
}); | |||
|
|||
|
|||
it('should respond with last matched definition', function() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention whenOverride
in the description or it is contradicting the one above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something like "should match against whenOverride
handlers before normal when
handlers"?
src/ngMock/angular-mocks.js
Outdated
* @ngdoc method | ||
* @name $httpBackend#whenOverride | ||
* @description | ||
* Creates a new backend definition that will override any already existing definitions with the same parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it is important t mention that it will take precendence over all previous definitions (even they have different parameters).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something along these lines:
Creates a new backend definition that is put at the front of the queue for matching.
This means that a matching `whenOverride` definition will always respond even if
there is a more specific `when` definition.
And then give some examples such as (thanks to @gkalpak):
Expected usage:
// Without "override":
$httpBackend.whenPOST('/foo').respond(1);
$httpBackend.whenPOST('/foo', {id: 1}).respond(2);
$http.post('/foo'); // --> 1
$http.post('/foo', {id: 1}); // --> 1
// With "overrride":
$httpBackend.whenPOST('/foo').respond(1);
$httpBackend.whenOverridePOST('/foo', {id: 1}).respond(2);
$http.post('/foo'); // --> 1
$http.post('/foo', {id: 1}); // --> 2
Potentially confusing usage:
// Without "override":
$httpBackend.whenPOST('/foo', {id: 1}).respond(1);
$httpBackend.whenPOST('/foo').respond(2);
$http.post('/foo'); // --> 2
$http.post('/foo', {id: 1}); // --> 1
// With "overrride":
$httpBackend.whenPOST('/foo', {id: 1}).respond(1);
$httpBackend.whenOverridePOST('/foo').respond(2);
$http.post('/foo'); // --> 2
$http.post('/foo', {id: 1}); // --> 2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great fast work @szimek.
The code looks good. If we can tighten up the docs then happy to land this.
This PR adds a new method to $httpBackend that allows to override any existing definition, by adding the new definition at the beginning of the definition list, not at the end of it, like $httpBackend.when does. Closes angular#11637
7193eae
to
fa04335
Compare
@petebacondarwin I've updated the docs according to your and @gkalpak's suggestions. Thanks! Let me know, if there's anything else. |
Hi @szimek - thanks for doing that. // Without "priority":
$httpBackend.whenPOST('/foo').respond(1);
$httpBackend.whenPOST('/foo', {id: 1}).respond(2);
$http.post('/foo'); // --> 1
$http.post('/foo', {id: 1}); // --> 1
// With "priority":
$httpBackend.whenPOST('/foo').respond(1);
$httpBackend.whenPOST('/foo', {id: 1}).priority(10).respond(2);
$http.post('/foo'); // --> 1
$http.post('/foo', {id: 1}); // --> 2 In other words we chain a method call onto the definition that allows us to set its "priority". Then handlers are sorted by this priority. |
No problem ;) The
and
are basically equivalent, because I don't think I'd need to mock the same request with different priorities in a single test. If I need to override a mock defined earlier in the same test, calling In our project we simply change |
Hold off on more changes @szimek before we can nail down something that everyone is happy with. |
@szimek - OK, so sorry about the indecision here. The core team have discussed it and have decided that the best strategy is to add a new configuration switch to The default will be the current handling strategy and you have to opt-in to get the latest-first strategy. This will ensure backward compatibility. Let me know what you think. Feel free to discuss a bit more here before implementing anything, if you want. |
@petebacondarwin Sounds good. I'm going away for 2 weeks, so I'll try to do that once I'm back. |
@petebacondarwin Hey, I might finally find some time tomorrow to tackle it. One question - do you think it's better to change the order of adding new definitions to the Regarding function name - what do you think about: $httpBackendProvider.handlerMatchingOrder('oldestFirst') // default setting
$httpBackendProvider.handlerMatchingOrder('latestFirst') ? I'm not sure about On the other hand in Anyway, I'll already start working on it and the provider function name can be, if needed, renamed later. EDIT: It might take a bit longer than expected, because I need to figure out how to add |
Great news @szimek! Regarding working around the decorator, perhaps we could afford to put this as method on the mock service itself? As long as it is set before you start adding matchers then it would be fine. You could just set it in an extra module, with a run block...
|
@szimek are you still planning on finishing this PR? Would be good to know so we can plan accordingly. |
…ttpBackend request Closes angular#16251 Closes angular#11637
…ttpBackend request Closes angular#16251 Closes angular#11637
What kind of change does this PR introduce? (Bug fix, feature, docs update, ...)
Feature
What is the current behavior? (You can also link to an open issue here)
As discussed in #11637 currently
$httpBackend.when
adds new definitions to the end of the list, making it hard to override any existing definitions.What is the new behavior (if this is a feature change)?
This PR adds a new method
$httpBackend.whenOverride
and its short methods (whenOverrideGET
etc.) that work almost exactly like$httpBackend.when
, but they add definition the the beginning of the list, allowing to override the existing definitions.Does this PR introduce a breaking change?
Nope.
Please check if the PR fulfills these requirements
Other information:
I'm not sure if I should simply copy docs for
$httpBackend.when
method and all the "short" methods (e.g.$httpBackend.whenGET
etc.) or if I should somehow modify/simplify them.CC @petebacondarwin