Angularjs 摩卡/角度单元测试从不运行';然后';功能

Angularjs 摩卡/角度单元测试从不运行';然后';功能,angularjs,unit-testing,asynchronous,mocha.js,karma-runner,Angularjs,Unit Testing,Asynchronous,Mocha.js,Karma Runner,我试图测试一个角度服务,它在mocha chai中返回一个承诺,但在单元测试中调用“then”超时。我的服务依赖于具有异步$resource请求的第二个服务。getData()应该在内部从所述异步服务获取数据,并将承诺传递给控制器,控制器对响应调用“then”函数。这在控制器中非常有效,在单元测试中绝对失败 服务代码: // use: myService.getData.then(...) works beautifully in angular controllers getData = fu

我试图测试一个角度服务,它在mocha chai中返回一个承诺,但在单元测试中调用“then”超时。我的服务依赖于具有异步$resource请求的第二个服务。getData()应该在内部从所述异步服务获取数据,并将承诺传递给控制器,控制器对响应调用“then”函数。这在控制器中非常有效,在单元测试中绝对失败

服务代码:

// use: myService.getData.then(...) works beautifully in angular controllers
getData = function(dataId) {
    var dataPromise;

    // get students from the api, if necessary, or from the service if already retrieved
    // dataList is a private property of the service
    if(!dataList) {
        dataPromise = asyncServiceUsedByMyService.asyncMethod({...}).$promise
            .then(
                function(response){


                  dataList = response;

                  doSomeDataManipulation();

                      return dataList;
                },
                function(err) {
                    return err;
                }
            );
    }
    // use the existing studentList if available
    else {
        dataPromise = $q.when(function(){
            return dataList
        });
    }

    return dataPromise;
};
测试代码

describe('Service Test', function() {
    var expect = chai.expect,
        myService,
        asyncServiceUsedByMyService;


    beforeEach(function() {

        var data,
            asyncServiceMock;

        data =[...];

        // mock the async dependency
        asyncServiceMock = {
            asynchMethod: function () {
                var deferred = q.defer();

                deferred.resolve(data);
                return {$promise: deferred.promise};
            }
        };

        module('myApp');

        module(function($provide){
            $provide.value('asyncServiceUsedByMyService', asyncServiceMock);
        });

        inject(function(myService, $q, asyncServiceUsedByMyService) {
            myService = myService;
            q = $q;
            courseEnrollmentService = courseEnrollmentServiceMock;
        });
    });

    // passes
    it('should be available', function() {
        expect(!!myService).to.equal(true);
    });

    // 'then' function is never called, unit test times out
    it('should get all items from async dependency', function(done) {
        myService.getData().then(function(response) {
            expect(response).to.have.property('length').that.equals(5);
            done();
        });
    });

});
我如何让myService的'then'函数在单元测试中运行,这样它就可以得到模拟数据(应该是即时的,因为我们没有进行实际的api调用?)

注意:我也尝试过“chai as promised”语法,但下面的代码似乎超时了

it('should get all items from async dependency', function(done) {
    expect(myService.getData()).to.eventually.have.property('length').that.equals(5).and.notify(done);
});

角度分辨率是在摘要循环中进行的,您可以通过调用
scope.$apply()触发此循环在您的测试中


你可以读更多

添加作用域。$apply()强制测试运行并通过或失败,但karma确实存在一个错误,即我的一些测试会导致重新加载整个页面。另外(可能与重新加载有关?)我不能再调试我的测试了。当我尝试在Chrome(默认的Karma浏览器)中调试Karma测试时,会出现NOT FOUND(404)错误,并且在Chrome开发工具中找不到javascript源代码。有没有更好的方法来测试异步承诺而不使用“then”和“apply”,因为Karma显然不能很好地处理apply?我一直在使用Karma,但Jasmine和promises从来都不是问题,所以我真的不知道您的测试发生了什么。