Closed OJezu closed 9 years ago
I found (via debugging api doc) I can set when.Promise.onFatalRejection
. Problem solved, but I think when.Promise.onFatalRejection
could get more exposition.
Dnia 13 lutego 2015 16:40:52 CET, Christopher Chrapka notifications@github.com napisał(a):
Closed #428.
Reply to this email directly or view it on GitHub: https://github.com/cujojs/when/issues/428#event-235455881
Hi,
This might end rather funky if you separate the unit tests from the main application, or do cross-module requires.
The way that require() caching works is that it will store a single copy of the module in its internal module map, indexed by name. However, if two copies are installed in different locations, even if one is a symlink to the other, you may find that the when module that you're monkey-patching is not the same object instance that the "when" your app is using. That is, it may be hard to prevent a split-brain module situation and as such relying on globals is not recommended. I have had a case of duplicate "when" modules in an application personally.
A better approach may be exposing an EventEmitter from your object/code and calling .emit('error') in .done()'s rejection callback. If no handler is registered, the process shall crash. Your tests can then call .on() and prevent this.
@rkaw92 You know, mocha has something like after()
. So...
it('should crash process', function(d){
var org_onFatalRejection = when.Promise.onFatalRejection;
after(function(){
when.Promise.onFatalRejection = org_onFatalRejection;
});
when.Promise.onFatalRejection = function(rejection){
try{
rejection.value.should.be.instanceOf(Errors.FatalError);
d();
} catch(err){
d(err);
}
};
(...)
});
@OhJeez, yes indeed, that is a fairly typical way to test something like onFatalRejection
. However, I think I might go for a more direct approach. If you simply assume that done
has been implemented correctly in when.js--that is, assume that if it's called, then it will indeed crash the process--then all you need to do is spy on done
. Testing that onFatalRejection
is called is probably too fine grained of an implementation detail to test.
For example, you could simply mock/spy/override when.Promise.prototype.done
, and then verify that it was called.
@rkaw92's point is a good one, though, and worth expanding on a bit. In a node app, it's entirely possible for multiple copies of when.js (or any package, for that matter) to be in play (via transitive dependencies). Each copy would have it's own when.Promise
constructor with its own onFatalRejection
property. It's just important to keep in mind that by overriding one of them, you won't be overriding them all. That's why it's important not to rely on being able to override it for all cases.
That's the impetus behind the new process
events in node and window
events in browsers in when >= 3.7.0. If all copies of when.js in play are emitting those, then its possible to observe them centrally. Other promise implementations have also added those events, as well. So, as long as all the copies of all the promise implementations in your app do that, it's possible to centrally observe all unhandled rejections.
As of right now, though, there's no 'fatalRejection` event.
@briancavalier I tried overwriting when.Promise.prototype.done
, but I had strange results. It had old behaviour (not-ovewritten) when tests were run, unless I used mocha --watch
in which case, on second run it indeed used the overwritten method. I think that prototype (or methods) must be copied at some point, and I didn't feel like searching through when code to see what is exactly happening.
Crap, [Reopen and comment] button is awfully big.
I have a scenario in which all I can do upon an error is crash the process (or pass to something that knows what to do with such things). I'm using
Promise.done()
for that. Problem is, I would like to unit test if in that scenario.done()
is called, but without crashing unit test process. So before hacking around in prototypes I would like to ask:Is there (or should be introduced) a "supported" way to do such testing?