Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add optionally() and make isDone and pendingMocks consistent. #723

Merged
merged 8 commits into from
Oct 20, 2016

Conversation

pimterry
Copy link
Contributor

This PR adds optionally(), so you can define mocks that might happen, but not worry about it if they don't (I'm using this for some common test setup where for almost every test in need a basic request mocked out, but not for all of them).

Along the way I noticed isDone() and pendingMocks() weren't actually consistent. Only isDone() ever considered persisted mocks to be 'done' (they stayed in pendingMocks() forever), and only isDone() supported options.requireDone (see below). I've now made them consistent so, tidied the implementations together, and simplified this significantly on the way.

There was an existing feature sort-of like optionally() already present: you could pass requireDone: false as an option to an interceptor. Passing as an option is less nice UX for my case, but more problematically it was previously inconsistent between pendingMocks (which ignored it) and isDone (which didn't), it wasn't undocumented anywhere, and it doesn't appear to have ever been used (no results in google or in code on github that aren't from direct copies of this codebase). I've removed this, since optionally() does the same thing. Could keep it, your call, but I'd just let it go IMO.

return this.reply(statusCode, readStream, headers);
};


Copy link
Contributor Author

Choose a reason for hiding this comment

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

As on #721, I'm not sure why this is here, presumably from a previous change that forgot to commit this.

Copy link
Contributor

Choose a reason for hiding this comment

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

This file is updated every time the tests are run. I'm trying to figure out a good enough way to avoid it muddling with the diffs (probably just gitignore it for a start).

@coveralls
Copy link

coveralls commented Oct 12, 2016

Coverage Status

Coverage increased (+0.01%) to 96.552% when pulling fd658ca on pimterry:optional-mocks into bc565eb on node-nock:master.

Copy link
Contributor

@vrinek vrinek left a comment

Choose a reason for hiding this comment

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

Code is good. Thanks! I would like to merge this soon.

The last comment (about the tests) is an extra. If you don't add it, no worries, I'll pick it up post-merge.

@@ -810,6 +811,23 @@ var scope = nock('http://api.myservice.com')
})
```

## Optional Requests

By default every mocked request is expected to be made exactly once, and until it is it'll appear in `scope.pendingMocks()`, and `scope.isDone()` will return false (see [expectations](#expectations)). In many cases this is fine, but in some (especially cross-test setup code) it's useful to be able to mock a request that may or may not happen. You can do this with `optionally()`. Optional requests do not appear in `pendingMocks()`, and `isDone()` will return true for scopes with only optional requests pending.
Copy link
Contributor

Choose a reason for hiding this comment

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

Worth mentioning here that "optional requests are consumed like normal ones once they are matched".

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

var interceptorList = self.keyedInterceptors[key];
var pendingInterceptors = interceptorList.filter(function (interceptor) {
var persistedAndUsed = self._persist && interceptor.interceptionCounter > 0;
return !persistedAndUsed && !interceptor.optional;
Copy link
Contributor

Choose a reason for hiding this comment

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

This piece of code (and the one it replaced) is hiding an assumption: when an interceptor has been fully consumed, it's removed from the keyedInterceptors list.

I would like to get rid of that assumption. This however would require a refactor that touches various parts of the codebase. In the spirit of keeping this PR on target, I would instead suggest adding a comment to document the fact and I'll add an issue to refactor it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

return pendingInterceptors.length > 0;
});

return pendingInterceptorKeys;
Copy link
Contributor

Choose a reason for hiding this comment

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

I see that pendingMocks was incorrectly returning all mocks. I expect that some users of nock may have depended of that behaviour.

Would you mind adding something like allMocks/remainingMocks/activeMocks (naming's hard) that's doing what pendingMocks was previously doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done - I've added this as activeMocks, since that's literally what it is I think: every mock that might actively handle a request.


t.ok(scope.isDone());
t.end();
});
Copy link
Contributor

Choose a reason for hiding this comment

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

With the code in this PR, I would expect a mock that's both optional and persist to be absent from pendingMocks but intercept requests multiple times.

Something analogous could be said about optional and times(n).

Would adding tests for these combined behaviours be an overkill?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

});

test('activeMocks returns optional mocks only before they\'re completed', function(t) {
nock.cleanAll();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd quite like to add a beforeEach() and do this cleanAll() before every test automatically, but that requires restructuring this whole file (at least) to wrap it all in a test scope, and I thought that was extending this PR a bit too far (especially since it makes the diff unreadable). Might be worth doing everywhere in future though, to make the tests a bit more isolated from one another.

Copy link
Contributor

Choose a reason for hiding this comment

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

The big idea is to drop tap in favour of mocha. If you're interested in helping out, drop by our Gitter channel. I plan on starting work on it over the weekend.

@coveralls
Copy link

coveralls commented Oct 17, 2016

Coverage Status

Coverage increased (+0.04%) to 96.582% when pulling 142c818 on pimterry:optional-mocks into bc565eb on node-nock:master.

@pimterry
Copy link
Contributor Author

All your markups sound sensible to me, so I've done the lot. Let me know if there's any other changes you need.

@vrinek vrinek merged commit d5962f2 into nock:master Oct 20, 2016
@vrinek
Copy link
Contributor

vrinek commented Oct 20, 2016

Thanks a lot for contributing to keep nock moving forward.

@vrinek
Copy link
Contributor

vrinek commented Oct 23, 2016

Published as part of v8.2.0 🎉

@pimterry pimterry deleted the optional-mocks branch November 16, 2016 16:52
@lock
Copy link

lock bot commented Sep 13, 2018

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue and add a reference to this one if it’s related. Thank you!

@lock lock bot locked as resolved and limited conversation to collaborators Sep 13, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants