在 angularjs 控制器中对承诺调用进行单元测试时遇到问题

Having problems unit testing a promise call in angularjs controller

本文关键字:单元测试 遇到 问题 调用 控制器 angularjs 承诺      更新时间:2023-09-26

SupportedLanguagesServices get方法返回一个promise,该在控制器中解析,如下所示:

    angular.module('App').controller('MyController', ['SupportedLanguagesService',
    function(SupportedLanguagesService) {
        var self = this;
        self.supportedLanguages = [];
        SupportedLanguagesService.get().success(
            function(response) {
                self.supportedLanguages = response;
        });
    }]);

这是我写的测试,但它不起作用:

    describe('Controller: MyController', function() {
    beforeEach(module('App'));
    var rootScope, controller;
    beforeEach(inject(function($controller, $rootScope, SupportedLanguagesService, $q) {
        var deferred = $q.defer();
        deferred.resolve([{name:"English", code:"en"},{name:"Portugues", code:"pt_BR"]);
        spyOn(SupportedLanguagesService, 'get').andReturn(deferred.promise);
        rootScope = $rootScope;
        controller = $controller;
    }));
    it('should get SupportedLanguages', function() {
        rootScope.$digest();
        var ctrl = controller('MyController');
        expect(ctrl.supportedLanguages.length).toEqual(2);
    });
});

它会在语句上引发异常:var ctrl = controller('MyController');

感谢您的协助。

Intead of success(这是一个$http回调),你可以更改为一个then,它在所有承诺上都可用。这将使您可以轻松地模拟承诺(并且不关心$httpBackend

    SupportedLanguagesService.get().then(
        function(response) {
            self.supportedLanguages = response.data;
    });
然后,

您需要使用控制器的构造函数,然后调用 $digest 。 因此,切换到此应该可以使您到达那里:

it('should get SupportedLanguages', function() {
    var ctrl = controller('MyController');
    rootScope.$digest();
    expect(ctrl.supportedLanguages.length).toEqual(2);
});

您还可以使用以下$q.when简化设置代码:

var response = [{name:"English", code:"en"},{name:"Portugues", code:"pt_BR"}];
spyOn(SupportedLanguagesService, 'get').andReturn($q.when(response));