凭借$ q和业力角度的承诺,mocha&柴

时间:2016-02-03 15:22:44

标签: javascript angularjs karma-runner karma-mocha

所以我试图在我的角度应用程序测试中得到承诺,任何人都可以弄清楚我在这里做错了它会一直回来:

Error: timeout of 2000ms exceeded. Ensure the done() callback is being called in this test.

我不知道它是否是$ q。

仅供参考我还尝试了it('test', function(done){... done();})

控制器

(function() {
    'use strict';

    angular
        .module('controller.editor', [])
        .controller('EditorController', EditorController);

    function EditorController($scope, $q) {
        var vm = this;

        angular.extend(vm, {
            hack: hack
        });

        function hack(bool) {
            return $q(function(resolve, reject) {
                if (bool) {
                    resolve(true);
                }

                reject(false);
            });
        }
    }
});

测试

describe('EditorController', function() {
    var vm, scope, $controller, $rootScope, $injector;

    beforeEach(function() {
        module('app');

        //Inject
        inject(function(_$injector_) {
            $injector = _$injector_;
            $controller = $injector.get('$controller');
            $rootScope = $injector.get('$rootScope');

            // Create new scope object
            scope = $rootScope.$new();

            // Bind the controller
            vm = $controller('EditorController', {
                $scope: scope
            });
        });
    });

    describe('#addCustom', function() {
        it('test', function(done) {
            var aHack = vm.hack(true);

            aHack.then(function(bool){
                // Resolve
                expect(bool).to.be.eq(true);
                done();
            }, function() {
                // Reject
                expect(bool).to.be.eq(false);
                done();
            });
        });
    });
});

2 个答案:

答案 0 :(得分:1)

当以角度测试承诺时,最好的做法是依靠角度机械来同步而不是异步地解决承诺。

这使代码更易于阅读和维护。

它也不容易出错;在.then()中进行断言是一种反模式,因为如果永远不会调用回调,那么断言永远不会运行。

要使用角度测试方法,您应该:

  1. 删除done
  2. 在测试中执行$rootScope.$digest()以解决承诺
  3. 做你的断言
  4. 将此应用于您的代码将是:

    describe('#addCustom', function() {
        it('test', function() {
            var __bool = false;
            var aHack = vm.hack(true).then(function(bool) {
                __bool = bool;
            });
    
            $rootScope.$digest();
    
            expect(__bool).to.be.eq(true);
        });
    });
    

    但它很棘手,因为$rootScope.$digest只解析$q个承诺,而不是所有的承诺,特别是不是通过Promise()构造函数从各种es5填充程序创建的承诺,请参阅:

    Promise resolved too late in angularjs jasmine test

    另见:

    http://brianmcd.com/2014/03/27/a-tip-for-angular-unit-tests-with-promises.html

答案 1 :(得分:-1)

问题在于,在设置“然后”之前,您的承诺已得到解决。行为。

看一下所有使用setTimeout的these examples