javascript - 使用 angular/karma/jasmine 模拟异步服务功能

标签 javascript angularjs asynchronous mocking karma-jasmine

这段代码中的测试没有成功。我似乎无法成功测试异步函数的返回。

describe('mocking services', function () {

    var someService, deferred;

    beforeEach(function () {

        module(function($provide){
            $provide.factory('someService', function($q){
                return{
                    trySynch: function(){
                        return 33;
                    },
                    tryAsynch: function(){
                        deferred = $q.defer();
                        return deferred.promise;
                    }
                };
            });
        });

        inject(function (_someService_) {
            someService = _someService_;
        });
    });

    it('should be able to test values from both functions', function () {
        expect(someService.trySynch()).toEqual(33);

        var retVal;
        someService.tryAsynch().then(function(r){
            retVal = r;
        });
        deferred.resolve(44);
        expect(retVal).toEqual(44);
    });

});

当我运行它时,出现以下错误:

Chrome 36.0.1985 (Mac OS X 10.9.4) mocking services should be able to test values from both functions FAILED
        Expected undefined to equal 44.
        Error: Expected undefined to equal 44.
            at null.<anonymous> (/Users/selah/WebstormProjects/macrosim-angular/test/spec/services/usersAndRoles-service-test.js:34:24)

我怎样才能通过这个测试?

最佳答案

当使用 $q 模拟异步调用时,由于 $q 的实现方式,您需要使用 $rootScope.$apply()

具体来说,.then 方法不会被同步调用,它被设计为始终是异步的,无论它是如何被调用的——同步或异步。

为实现这一点,$q 与 $rootScope 集成在一起。因此,在您的单元测试中,您需要通知 $rootScope 某些内容已更改(即 - 触发摘要循环)。为此,您调用 $rootScope.$apply()

参见 here (specifically the "Differences between Kris Kowal's Q and $q section")

工作代码如下所示:

describe('mocking services', function () {

    var someService, deferred, rootScope;

    beforeEach(function () {

        module(function($provide){
            $provide.factory('someService', function($q){
                return{
                    trySynch: function(){
                        return 33;
                    },
                    tryAsynch: function(){
                        deferred = $q.defer();
                        return deferred.promise;
                    }
                };
            });
        });

        inject(function ($injector) {
            someService = $injector.get('someService');
            rootScope = $injector.get('$rootScope');
        });
    });

    it('should be able to test values from both functions', function () {
        expect(someService.trySynch()).toEqual(33);

        var retVal;
        someService.tryAsynch().then(function(r){
            retVal = r;
        });
        deferred.resolve(44);
        rootScope.$apply();
        expect(retVal).toEqual(44);
    });

});

关于javascript - 使用 angular/karma/jasmine 模拟异步服务功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25274150/

相关文章:

javascript - 如何在其模板中使用 View 属性?

javascript - 如何制作一个按钮来切换两个功能?

javascript - 当加载和渲染 html 中的图像时,是否存在类似就绪事件的事件?

javascript - 如何在初始化之前隐藏 Angular 表达式

javascript - 如何在 es6 javascript 类中使用 async/await?

javascript - 尝试使用 googlemaps api 和 javascript 查找两个 LatLng 对象之间的距离

angularjs - 依赖性破坏了应用程序

angularjs - 未知的提供者 : ngGridProvider <- ngGrid

c# - 异步执行存储过程而不等待它并阻塞 UI

javascript - 当必须首先在服务器上生成图像时,将图像异步预加载到浏览器缓存中