Imp*_*rks 11 unit-testing jasmine angularjs typescript
我正在为Typescript中的应用程序编写Jasmine单元测试并通过Resharper运行它们.如果处理程序抛出异常,它应该执行一个动作:
describe("Q Service Test", () => {
var q: ng.IQService;
var rootScope: ng.IRootScopeService;
beforeEach(inject(($q, $rootScope) => {
q = $q;
rootScope = $rootScope;
}));
it("Caught exceptions are handled properly", () => {
var state = 'ok';
q.when(1)
.then(() => {
throw new Error("test exception");
})
.catch(() => {
state = 'error';
});
rootScope.$digest();
expect(state).toBe('error');
});
});
Run Code Online (Sandbox Code Playgroud)
但是,测试失败了:

这是我的测试环境/工具的一些奇怪的行为,还是我错误地使用了promise机制本身?
rye*_*lar 15
您肯定错误地使用了promise机制,抛出用户定义的throw语句并不构成将其作为承诺拒绝正确使用.如$q文档中所述:
在将deferreds/promises与熟悉的try/catch/throw行为进行比较时,请将reject视为JavaScript中的throw关键字.这也意味着如果您通过promise错误回调"捕获"错误并且您希望将错误转发到从当前promise中派生的promise,则必须通过返回通过reject构造的拒绝来"重新抛出"错误.
它们类似但不等同,为了捕获用户定义的throw语句,你应该使用catch语句块.虽然$q承诺应该只catch拒绝承诺.因此,在您的情况下,返回拒绝的promise是处理进程的正确方法,而不是抛出用户定义的异常.
JAVASCRIPT
describe('Q Service Test', function() {
var $q,
$rootScope;
beforeEach(inject(function(_$q_, _$rootScope_) {
$q = _$q_;
$rootScope = _$rootScope_;
}));
it('Rejected promises are handled properly', function() {
var state = 'ok';
$q.when(1)
.then(function() {
return $q.reject('rejected');
})
.catch(function() {
state = 'error';
});
$rootScope.$digest();
expect(state).toBe('error');
});
});
Run Code Online (Sandbox Code Playgroud)
更新:
您的代码在浏览器中以这种方式运行的原因是因为Angular的$q实现try/catch在处理promise队列时使用了语句块.当任何回调抛出任何错误时,它会捕获错误本身,以异常作为拒绝原因拒绝它,之后它用于$exceptionHandler记录错误.我建议你简单地回复被拒绝的承诺.
至于单元测试这样做的原因是因为angular-mocks实现$exceptionHandler与实际应用程序不同$exceptionHandler.前者创建一个具有不同模式的提供程序,默认的角度模拟实现使用rethrow模式,而模式又抛出异常而不是记录它.如果您希望单元测试的行为与默认应用程序的行为方式相同,$exceptionHandler则可以将模式设置为'log'.
JAVASCRIPT
describe('Q Service Test', function() {
var $q,
$rootScope;
beforeEach(module('ng', function($exceptionHandlerProvider) {
$exceptionHandlerProvider.mode('log');
}));
beforeEach(inject(function(_$q_, _$rootScope_) {
$q = _$q_;
$rootScope = _$rootScope_;
}));
it('Caught exceptions are handled properly', function() {
var state = 'ok';
$q.when(1)
.then(function() {
throw new Error();
})
.catch(function() {
state = 'error';
});
$rootScope.$digest();
expect(state).toBe('error');
});
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3988 次 |
| 最近记录: |