无法迁移到角1.6.3之后测试被拒绝的承诺(Unable to test a rejected pr

2019-09-28 09:41发布

我最近更新的角度,从1.5我的应用程序1.6.3和开始变得茉莉花单元测试失败(与PhantomJS)围绕我已经写了基于承诺的代码:

可能未处理的拒绝:未定义抛出

阅读我周围看到,接受的解决办法是链条。那么()与.catch()块来妥善地处理拒绝。

我已经为我测试来证明这一点得到过去它做错误的我源文件中的一个做到了这一点。

然而,现在已经发现了另一个问题,其中的预期时,承诺拒绝被称为在我的代码我测试不再传递。

这是我想测试功能(后添加所需的catch块)

public deleteSomething = (thing) => {
    return this.UserMessages.buildConfirmDialog().then(() => {
        this.someService.remove(thing)
            .then(() => {
                this.UserMessages.showToast('Something deleted');
            })
            .catch((error) => {
                //handle error
            });
    })
    .catch((error) => {
        //handle error
    });
}

这里是测试:

var thing = {foo: 'bar'},
    deferredRemove,
    deferredConfirm,
    //Mock service below injected into controller later on before test are run
    UserMessages = {
        buildConfirmDialog: jasmine.createSpy('buildConfirmDialog').and.callFake(function() {
            deferredConfirm = $q.defer();
            return deferredConfirm.promise.catch(angular.noop);
        })
    };

//Inject and controller setup here...

    describe('When deleting something', function() {
        beforeEach(function() {
            deferredRemove = $q.defer();
            spyOn(someService, 'remove').and.returnValue(deferredRemove.promise.catch(angular.noop));
        });
        describe('and the user confirms the deletion', function() {
            beforeEach(function() {
                ctrl.deleteSomething(thing);
                deferredConfirm.resolve();
                deferredRemove.resolve();
                $rootScope.$apply();
            });
            it('should call remove on someService', function() {
                console.log('someService.remove.calls = ' + someService.remove.calls.count());
                expect(someService.remove).toHaveBeenCalled();
            });
        });
        describe('and the user cancels the deletion', function() {
            beforeEach(function() {
                someService.remove.calls.reset();
                vm.deleteSomething(thing);
                deferredConfirm.reject({});
                $rootScope.$apply();
            });
            it('should not call remove on someService', function() {
                console.log('someService.remove.calls = ' + someService.remove.calls.count());
                expect(someService.remove.calls.count()).toEqual(0);
            });
        });
    });

我没有了.catch(angular.noop)在之前的部分升级到1.6.3,并看到一些帖子暗示要做到这一点,为了让测试开心,这让过去在未处理的废品肯定有助于我我试运行。

我现在面临的问题是,对于拒绝测试规范,不应该有我的服务给remove函数调用制成,所以电话的数量应该是零,但它不断出来为1。我说行重置在我的测试呼叫,以确保它不是先前的测试贡献(我知道电话是为了测试之间进行复位)。

该测试运行得很好,当我是在1.5,所以这是一些我的代码\测试编写不与1.6.x的变化很好地玩的方式

有人能阐明什么可怎么回事,请一些轻?

谢谢

Answer 1:

我没有了.catch(angular.noop)在之前的部分升级到1.6.3,并看到一些帖子暗示要做到这一点,为了让测试开心,这让过去在未处理的废品肯定有助于我我试运行。

添加.catch(angular.noop)肯定会处理未处理的拒绝。

它把被拒绝的承诺兑现一个承诺!

您的测试是否正确失败,因为你打破了你的代码。

欲了解更多信息,请参见捕捉方法不使用$ HTTP GET请求工作


更改$ Q为AngularJS V1.6

报告承诺与非拒绝回调

拒绝没有一个回调来处理拒绝报告这承诺$exceptionHandler ,使他们能够登录到控制台。

重大更改

未处理的拒绝承诺将被记录到$exceptionHandler

依赖于特定的顺序或在信息的数量测试$exceptionHandler需要处理拒绝承诺报告。

治疗引发的错误定期拒绝

此前,在承诺的引发的错误onFulfilledonRejected处理程序在一个稍微不同的方式比普通的拒绝接受治疗:他们被传递到$exceptionHandler()除了被转换成拒绝)。

此行为的理由是,未被捕获的错误是比普通的排斥不同,因为它可以通过一个编程错误造成的,例如。 在实践中,这竟然是混淆或不理想的用户,因为无论是本地的承诺,也没有任何其他流行的诺言库区别于普通拒绝引发的错误。 (注:虽然这种行为并不违背承诺/ A +规格 ,它也不会被规定。)

这种承诺消除了区别,通过跳过调用$exceptionHandler()从而治疗引发的错误定期拒绝。

注意:除非明确地关闭,可能未处理拒绝仍将被捕获,并传递到$exceptionHandler()所以错误抛出由于编程错误,而不是其他方式处理(与随后onRejected处理)将不会被忽视。

欲了解更多信息,请参阅AngularJS开发指南-从V1.5迁移到V1.6



Answer 2:

通过此配置禁用可能未处理的拒绝 ,并再次测试。

app.config(['$qProvider', function ($qProvider) {
    $qProvider.errorOnUnhandledRejections(false);
}]);


文章来源: Unable to test a rejected promise after migrating to Angular 1.6.3