首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >单元测试angularjs $q.all -承诺永远不会完成

单元测试angularjs $q.all -承诺永远不会完成
EN

Stack Overflow用户
提问于 2014-11-05 07:33:14
回答 2查看 6.5K关注 0票数 8

我正在尝试测试我构建的一个服务,它使用了Angular的承诺的$q实现。我使用的组合卡玛,摩卡,柴,西农,西农柴和柴承诺。

我编写的所有测试和返回的承诺都通过了,但拒绝或使用$q.all([ ... ])的测试除外。我已尽我所能,但似乎找不到问题所在。

下面是我正在测试的一个苗条版本:

代码语言:javascript
复制
"use strict";


describe("Promise", function () {

    var $rootScope,
        $scope,
        $q;

    beforeEach(angular.mock.inject(function (_$rootScope_, _$q_) {
        $rootScope = _$rootScope_;
        $q = _$q_;
        $scope = $rootScope.$new();
    }));

    afterEach(function () {
        $scope.$apply();
    });

    it("should resolve promise and eventually return", function () {

        var defer = $q.defer();

        defer.resolve("incredible, this doesn't work at all");

        return defer.promise.should.eventually.deep.equal("incredible, this doesn't work at all");
    });

    it("should resolve promises as expected", function () {

        var fst = $q.defer(),
            snd = $q.defer();

        fst
            .promise
            .then(function (value) {
                value.should.eql("phew, this works");
            });

        snd
            .promise
            .then(function (value) {
                value.should.eql("wow, this works as well");
            });

        fst.resolve("phew, this works");
        snd.resolve("wow, this works as well");

        var all = $q.all([
            fst.promise,
            snd.promise
        ]);

        return all.should.be.fullfiled;
    });

    it("should reject promise and eventually return", function () {
        return $q.reject("no way, this doesn't work either?").should.eventually.deep.equal("no way, this doesn't work either?");
    });

    it("should reject promises as expected", function () {

        var promise = $q.reject("sadly I failed for some stupid reason");

        promise
            ["catch"](function (reason) {
                reason.should.eql("sadly I failed for some stupid reason");
            });

        var all = $q.all([
            promise
        ]);

        return all.should.be.rejected;
    });

});

第三次、最后一次和第一次测试都失败了。实际上,它没有失败,它只是在超时之后解决,我得到了一个Error: timeout of 2000ms exceeded

编辑:我刚刚试着用克里斯·科瓦尔的承诺实现进行测试,它运行得很好。

P.S. --我发现在摩卡、柴或柴湾的碗里花了一些时间,而afterEach钩子在超时之后才被调用。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-11-14 08:13:48

我试图找出为什么这些测试没有通过,尽管乍一看应该是这样。当然,我将不得不将$scope.$apply();afterEach中移开,因为这里不是@proloser所提到的调用的地方。

即使我这样做了,测试仍然没有通过。我还在柴应生角度上打开了一些问题,看看我是否得到了任何输入/反馈,并且我实际上已经被告知它很可能无法工作。究其原因,可能是因为角$q对文摘阶段的依赖,而这一点在chai promsied库中没有考虑到。

因此,我用问:而不是$q检查了测试,并且它运行得很好,从而加强了我的假设,即错误不是在所承诺的chai库中。

我最终放弃了所承诺的chai,并且我用Mocha的done回调重写了我的测试(尽管在幕后,chai答应也是这样做的):

代码语言:javascript
复制
"use strict";


describe("Promise", function () {

    var $rootScope,
        $scope,
        $q;

    beforeEach(angular.mock.inject(function (_$rootScope_, _$q_) {
        $rootScope = _$rootScope_;
        $q = _$q_;
        $scope = $rootScope.$new();
    }));

    it("should resolve promise and eventually return", function (done) {

        var defer = $q.defer();

        defer
            .promise
            .then(function (value) {
                value.should.eql("incredible, this doesn't work at all");
                done();
            });

        defer.resolve("incredible, this doesn't work at all");

        $scope.$apply();

    });

    it("should resolve promises as expected", function (done) {

        var fst = $q.defer(),
            snd = $q.defer();

        fst
            .promise
            .then(function (value) {
                value.should.eql("phew, this works");
            });

        snd
            .promise
            .then(function (value) {
                value.should.eql("wow, this works as well");
            });

        fst.resolve("phew, this works");
        snd.resolve("wow, this works as well");

        var all = $q.all([
            fst.promise,
            snd.promise
        ]);

        all
            .then(function () {
                done();
            });

        $scope.$apply();

    });

    it("should reject promise and eventually return", function (done) {

        $q
            .reject("no way, this doesn't work either?")
            .catch(function (value) {
                value.should.eql("no way, this doesn't work either?");
                done();
            });

        $scope.$apply();

    });

    it("should reject promises as expected", function (done) {

        var promise = $q.reject("sadly I failed for some stupid reason");

        promise
            ["catch"](function (reason) {
                reason.should.eql("sadly I failed for some stupid reason");
            });

        var all = $q.all([
            promise
        ]);

        all
            .catch(function () {
                done();
            });

        $scope.$apply();

    });

});

上述测试都将如预期一样通过。也许还有其他的方法,但我想不出其他的方法,所以如果有其他人这样做的话,最好能把它贴出来,这样其他人就能从中受益。

票数 3
EN

Stack Overflow用户

发布于 2014-11-09 07:30:10

afterEach()用于清理,不是用于在准备之后执行代码,而是用于在测试之前执行代码。$scope.$apply()也没有清理。

您需要做以下工作:

代码语言:javascript
复制
// setup async behavior
var all = $q.all(x.promise, y.promise)

// resolve your deferreds/promises
x.reject(); y.reject();

// call $scope.$apply() to 'digest' all the promises
$scope.$apply();

// test the results
return all.should.be.rejected;

测试完成后,您正在执行$apply(),而不是在安装和评估之间。

票数 13
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26751846

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档