为什么我的$ q推迟不在Angular单元测试中解决?

时间:2014-02-27 22:43:48

标签: javascript angularjs unit-testing

我正在努力让我的第一个 Angular单元测试工作。我对很多概念都很陌生,但是由于我已经不得不跳过很多障碍才能实现这一目标,所以我发布的是代码。我见过类似的问题,但没有一个帮助我解决这个问题。

这是一个控制器:

.controller('ThumbsCtrl', 
    ['$scope', 'backend', function($scope, backend) {
        backend.getImages()
            .then(function(images) {
                console.log("promise.then() called with "+images);
                $scope.images = images;
            }, function(err) {
               console.log(err);
            });
       }]
)

这是一个测试:

describe('ThumbsCtrl', function() {
    var controller, rootScope;
    beforeEach(module('myApp.controllers'));
    beforeEach(inject(function($controller, $rootScope) {
        controller = $controller;
        rootScope = $rootScope;
    }));

    it('should contain images', inject(function($q) {
        var scope = rootScope.$new();
        var backend = {
            getImages: function() { 
                console.log("calling mock getImages()");
                var deferred = $q.defer();
                deferred.resolve('shite');
                return deferred.promise;
            }
        };
        var ctrl = controller('ThumbsCtrl', {
            $scope: scope,
            backend: backend
        });

        expect(scope.images).toContain('shite');
    }));
});

测试失败,因为$ scope.images从未设置过。

抛开关于让我的控制器的构造函数调用异步方法(实际的backend.getImages()也返回一个承诺)的完整性的评论,任何人都可以告诉我为什么.then()调用中的成功或失败方法都没有被称为?我的理解是通过像我一样调用deferred.resolve(),单元测试确实应该没有异步代码。但显然我错了......对吗?

2 个答案:

答案 0 :(得分:4)

嗯,我通过添加:

来实现它
scope.$digest();

在最终期望之前()。我会把这一点归结为仍然被$ q deferreds感到困惑。我来自使用Parse.com JS SDK,当它们已经调用resolve()时,它的Promises是同步的。我猜$ q deferreds仍然保持异步,即使解决了上述问题?

作为旁注,Angular支持并且很好地记录如何进行单元测试的断言并不是那么真实。我正在交叉引用AngularJS文档,一本优秀的书籍(使用AngularJS掌握Web开发),以及两者的示例代码,我发现在阅读所有这些来源一周后相当突出,我在编写简单的单元测试时遇到了麻烦。要学习的概念数量很大,我之前也没有使用过Jasmine(使用过QUnit)。我试图推迟使用Karma,所以我可以一步一步,但是jeez - 如果我不关心单元测试,我现在就跳过它来编写我的愚蠢应用程序。

答案 1 :(得分:2)

如果它有助于我遇到与您相同的问题。我现在有了一个标准,我按照所有的承诺要求放置。

afterEach(function() {
    scope.$digest();
    mockBackend.flush();
    mockBackend.verifyNoOutstandingExpectation();
    mockBackend.verifyNoOutstandingRequest();

});

这确保没有未完成的$ http请求,并且所有内容都已经过正确测试。

我同意让很多这些单元测试运行起来非常麻烦,特别是测试指令。